diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..8001d1a --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn app:app \ No newline at end of file diff --git a/README.md b/README.md index ef1a0f6..8b74b02 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # core-python LineMob Core in Python +Using Flask and Deploy on Heroku + +run "pip freeze > requirments.txt" before deploy \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..565baaf --- /dev/null +++ b/app.py @@ -0,0 +1,47 @@ +from flask import Flask, request, abort + +from linebot import ( + LineBotApi, WebhookHandler +) +from linebot.exceptions import ( + InvalidSignatureError +) +from linebot.models import ( + MessageEvent, TextMessage, TextSendMessage, +) +from src.receiver import Receiver +app = Flask(__name__) + + +handler = WebhookHandler('cc19d3de5e1f7201cdbff7f0e8dfbf3e') + + +@app.route('/') +def index(): + return "

Hello I'm fine!

" + + +@app.route("/callback", methods=['POST']) +def callback(): + # get X-Line-Signature header value + signature = request.headers['X-Line-Signature'] + + # get request body as text + body = request.get_data(as_text=True) + app.logger.info("Request body: " + body) + # handle webhook body + try: + handler.handle(body, signature) + except InvalidSignatureError: + abort(400) + return 'OK' + + +@handler.add(MessageEvent, message=TextMessage) +def handle_message(event): + print('receiver here!') + receiver = Receiver(event) + + +if __name__ == "__main__": + app.run() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2c058ef --- /dev/null +++ b/requirements.txt @@ -0,0 +1,28 @@ +auth==0.5.3 +blinker==1.4 +click==6.7 +Django==1.10.6 +enum-compat==0.0.2 +enum34==1.1.6 +eventlet==0.20.1 +falcon==1.1.0 +Flask==0.12 +future==0.16.0 +greenlet==0.4.12 +gunicorn==19.7.0 +helper==2.4.2 +imgurpython==1.1.7 +itsdangerous==0.24 +Jinja2==2.9.5 +line-bot-sdk==1.3.0 +MarkupSafe==1.0 +mongoengine==0.11.0 +psycopg2==2.7.1 +pymongo==3.4.0 +python-firebase==1.2 +python-mimeparse==1.6.0 +PyYAML==3.12 +requests==2.13.0 +six==1.10.0 +virtualenv==15.1.0 +Werkzeug==0.12.1 diff --git a/src/Template/ImageMessage.py b/src/Template/ImageMessage.py new file mode 100644 index 0000000..7175461 --- /dev/null +++ b/src/Template/ImageMessage.py @@ -0,0 +1,13 @@ +from linebot.models import ( + ImageSendMessage, +) + + +class ImageMessage(): + + def __init__(self, command): + self.original_content_url = command.get_message()['original_content_url'] + self.preview_image_url = command.get_message()['preview_image_url'] + + def get(self): + return ImageSendMessage(self.original_content_url,self.preview_image_url) diff --git a/src/Template/LocationMessage.py b/src/Template/LocationMessage.py new file mode 100644 index 0000000..e8dc5c8 --- /dev/null +++ b/src/Template/LocationMessage.py @@ -0,0 +1,15 @@ +from linebot.models import ( + LocationSendMessage, +) + + +class LocationMessage(): + + def __init__(self, command): + self.title = command.get_message()['title'] + self.address = command.get_message()['address'] + self.latitude = command.get_message()['latitude'] + self.longitude = command.get_message()['longitude'] + + def get(self): + return LocationSendMessage(self.title, self.address, self.latitude, self.longitude) diff --git a/src/Template/MessageTemplateFactory.py b/src/Template/MessageTemplateFactory.py new file mode 100644 index 0000000..8eefe0f --- /dev/null +++ b/src/Template/MessageTemplateFactory.py @@ -0,0 +1,24 @@ +from .TextTemplate import TextTemplate +from .ImageMessage import ImageMessage +from .LocationMessage import LocationMessage +from .StickerMessage import StickerMessage +from .TemplateMessage import TemplateMessage + + +class MessageTemplateFactory(): + + def __init__(self, command): + self.command = command + if self.command.get_template() == 'TextMessage': + self.template = TextTemplate(self.command).get() + elif self.command.get_template() == 'ImageMessage': + self.template = ImageMessage(self.command).get() + elif self.command.get_template() == 'LocationMessage': + self.template = LocationMessage(self.command).get() + elif self.command.get_template() == 'StickerMessage': + self.template = StickerMessage(self.command).get() + elif self.command.get_template() == 'TemplateMessage': + self.template = TemplateMessage(self.command).get() + + def get(self): + return self.template diff --git a/src/Template/StickerMessage.py b/src/Template/StickerMessage.py new file mode 100644 index 0000000..e056b19 --- /dev/null +++ b/src/Template/StickerMessage.py @@ -0,0 +1,13 @@ +from linebot.models import ( + StickerSendMessage, +) + + +class StickerMessage(): + + def __init__(self, command): + self.package_id = command.get_message()['package_id'] + self.sticker_id = command.get_message()['sticker_id'] + + def get(self): + return StickerSendMessage(self.package_id, self.sticker_id) diff --git a/src/Template/TemplateMessage.py b/src/Template/TemplateMessage.py new file mode 100644 index 0000000..a7a5f4b --- /dev/null +++ b/src/Template/TemplateMessage.py @@ -0,0 +1,13 @@ +from linebot.models import ( + TemplateSendMessage, +) + + +class TemplateMessage(): + + def __init__(self, command): + self.alt_text = command.get_message()['alt_text'] + self.template = command.get_message()['template'] + + def get(self): + return TemplateSendMessage(self.alt_text, self.template) diff --git a/src/Template/TextTemplate.py b/src/Template/TextTemplate.py new file mode 100644 index 0000000..f622e32 --- /dev/null +++ b/src/Template/TextTemplate.py @@ -0,0 +1,12 @@ +from linebot.models import ( + TextSendMessage, +) + + +class TextTemplate(): + + def __init__(self, command): + self.text = command.get_message() + + def get(self): + return TextSendMessage(self.text) diff --git a/src/Template/__init__.py b/src/Template/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/command/__init__.py b/src/command/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/command/command.py b/src/command/command.py new file mode 100644 index 0000000..4a570e1 --- /dev/null +++ b/src/command/command.py @@ -0,0 +1,34 @@ +class Command(): + + def __init__(self): + self.event = None + self.command = None + self.template = None + self.message = None + + def set_event(self, event): + self.event = event + + def get_event(self): + return self.event + + def set_command(selt, command): + self.command = command + + def get_command(self): + return self.command + + def set_template(self, template): + self.template = template + + def get_template(self): + return self.template + + def set_message(self, message): + self.message = message + + def get_message(self): + return self.message + + def isValidCmd(self): + raise NotImplementedError("Please Implement this method") diff --git a/src/command/command1.py b/src/command/command1.py new file mode 100644 index 0000000..492f949 --- /dev/null +++ b/src/command/command1.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command1(Command): + + def __init__(self): + self.event = None + self.command = '1' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command2.py b/src/command/command2.py new file mode 100644 index 0000000..3d006f8 --- /dev/null +++ b/src/command/command2.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command2(Command): + + def __init__(self): + self.event = None + self.command = '2' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command3.py b/src/command/command3.py new file mode 100644 index 0000000..2d9455e --- /dev/null +++ b/src/command/command3.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command3(Command): + + def __init__(self): + self.event = None + self.command = '3' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command4.py b/src/command/command4.py new file mode 100644 index 0000000..d7d56b5 --- /dev/null +++ b/src/command/command4.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command4(Command): + + def __init__(self): + self.event = None + self.command = '4' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command5.py b/src/command/command5.py new file mode 100644 index 0000000..74d3c69 --- /dev/null +++ b/src/command/command5.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command5(Command): + + def __init__(self): + self.event = None + self.command = '5' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command6.py b/src/command/command6.py new file mode 100644 index 0000000..97a1ff1 --- /dev/null +++ b/src/command/command6.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command6(Command): + + def __init__(self): + self.event = None + self.command = '6' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command7.py b/src/command/command7.py new file mode 100644 index 0000000..e862ea8 --- /dev/null +++ b/src/command/command7.py @@ -0,0 +1,13 @@ +from .command import Command + + +class Command7(Command): + + def __init__(self): + self.event = None + self.command = '7' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/commandDefault.py b/src/command/commandDefault.py new file mode 100644 index 0000000..b8cfc68 --- /dev/null +++ b/src/command/commandDefault.py @@ -0,0 +1,13 @@ +from .command import Command + + +class CommandDefault(Command): + + def __init__(self): + self.event = None + self.command = 'commandDefault' + self.template = None + self.message = None + + def isValidCmd(self): + return self.event.message.text == self.command diff --git a/src/command/command_registry.py b/src/command/command_registry.py new file mode 100644 index 0000000..6aba09b --- /dev/null +++ b/src/command/command_registry.py @@ -0,0 +1,52 @@ +from linebot.models import ( + TextMessage, StickerMessage, LocationMessage, ImageMessage, VideoMessage, AudioMessage +) +from .command import Command +from .commandDefault import CommandDefault + + +class CommandRegistry(): + + def __init__(self, event): + self.event = event + self.command_list = list() + + def add_command(self, command): + self.command_list.append(command) + + def get_command(self): + if isinstance(self.event.message, TextMessage): + return self.get_text_message_command() + elif isinstance(self.event.message, StickerMessage): + pass + elif isinstance(self.event.message, LocationMessage): + pass + elif isinstance(self.event.message, ImageMessage): + pass + elif isinstance(self.event.message, VideoMessage): + pass + elif isinstance(self.event.message, AudioMessage): + pass + + def get_text_message_command(self): + for command in self.command_list: + command.set_event(self.event) + if isinstance(command, CommandDefault): + return command + if command.isValidCmd(): + return command + + def get_sticker_message_command(self): + pass + + def get_location_message_command(self): + pass + + def get_image_message_command(self): + pass + + def get_video_message_command(self): + pass + + def get_audio_message_command(self): + pass diff --git a/src/command_bus.py b/src/command_bus.py new file mode 100644 index 0000000..1ef2bdd --- /dev/null +++ b/src/command_bus.py @@ -0,0 +1,41 @@ +from .middleware.hello_middleware import HelloMiddleware +from .middleware.button_template_middleware import ButtonTemplateMiddleware +from .middleware.carousel_template_middleware import CarouselTemplateMiddleware +from .middleware.confirm_template_middleware import ConfirmTemplateMiddleware +from .middleware.default_message_middleware import DefaultMessageMiddleware +from .middleware.image_message_middleware import ImageMiddleware +from .middleware.location_message_middleware import LocationMessageMiddleware +from .middleware.sticker_message_middleware import StickerMessageMiddleware +from .handler import Handler + + +class CommandBus(): + + def __init__(self, command): + self.command = command + self.middleware = list() + self.initial() + self.run() + + def initial(self): + self.add(HelloMiddleware()) + self.add(ButtonTemplateMiddleware()) + self.add(CarouselTemplateMiddleware()) + self.add(ConfirmTemplateMiddleware()) + self.add(DefaultMessageMiddleware()) + self.add(ImageMiddleware()) + self.add(LocationMessageMiddleware()) + self.add(StickerMessageMiddleware()) + + def add(self, middleware): + self.middleware.append(middleware) + + def get(self, index): + return self.middleware[index] + + def run(self): + for middleware in self.middleware: + middleware.execute(self.command) + if(not middleware.next()): + break + handler = Handler(self.command) diff --git a/src/handler.py b/src/handler.py new file mode 100644 index 0000000..63f1089 --- /dev/null +++ b/src/handler.py @@ -0,0 +1,19 @@ +from linebot import ( + LineBotApi, WebhookHandler +) + +from .Template.MessageTemplateFactory import MessageTemplateFactory + + +class Handler(): + + def __init__(self, command): + self.command = command + self.template = MessageTemplateFactory(self.command).get() + self.sendMessage() + + def sendMessage(self): + line_bot_api = LineBotApi( + 'hMMdUsmj1Mq7JmTo3x0gCh/L6WilPgxU5UfCEh24aHQNad8NOAMu8+4XdaKgFMzcG4nO+CSf/vVHMJ+4MvtBLV+akhxxXChn3X5tD0dPE+M/ixVqml7WFi2baNlzz7izNNXmL4LlnL56eZs1Dh4m9QdB04t89/1O/w1cDnyilFU=') + line_bot_api.reply_message( + self.command.event.reply_token, self.template) diff --git a/src/middleware/__init__.py b/src/middleware/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/middleware/button_template_middleware.py b/src/middleware/button_template_middleware.py new file mode 100644 index 0000000..5cbb8ab --- /dev/null +++ b/src/middleware/button_template_middleware.py @@ -0,0 +1,37 @@ +from linebot.models import ( + ButtonsTemplate, PostbackTemplateAction, MessageTemplateAction, URITemplateAction +) +from .middleware import Middleware + + +class ButtonTemplateMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '6' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message({'alt_text': 'Buttons template', + 'template': ButtonsTemplate( + thumbnail_image_url='https://example.com/image.jpg', + title='Menu', + text='Please select', + actions=[ + PostbackTemplateAction( + label='postback', + text='postback text', + data='action=buy&itemid=1' + ), + MessageTemplateAction( + label='message', + text='message text' + ), + URITemplateAction( + label='uri', + uri='http://example.com/' + ) + ] + ) + }) + command.set_template('TemplateMessage') diff --git a/src/middleware/carousel_template_middleware.py b/src/middleware/carousel_template_middleware.py new file mode 100644 index 0000000..0406342 --- /dev/null +++ b/src/middleware/carousel_template_middleware.py @@ -0,0 +1,62 @@ +from linebot.models import ( + CarouselTemplate, CarouselColumn, ConfirmTemplate, PostbackTemplateAction, MessageTemplateAction, URITemplateAction +) +from .middleware import Middleware + + +class CarouselTemplateMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '7' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message({'alt_text': 'Carousel template', + 'template': CarouselTemplate( + columns=[ + CarouselColumn( + thumbnail_image_url='https://i.pinimg.com/736x/48/bd/3f/48bd3f6e928d7cb4b8d499cb0f96b8a8--despicable-minions-funny-minion.jpg', + title='this is menu1', + text='description1', + actions=[ + PostbackTemplateAction( + label='postback1', + text='postback text1', + data='action=buy&itemid=1' + ), + MessageTemplateAction( + label='message1', + text='message text1' + ), + URITemplateAction( + label='uri1', + uri='https://i.pinimg.com/736x/48/bd/3f/48bd3f6e928d7cb4b8d499cb0f96b8a8--despicable-minions-funny-minion.jpg' + ) + ] + ), + CarouselColumn( + thumbnail_image_url='https://i.pinimg.com/736x/48/bd/3f/48bd3f6e928d7cb4b8d499cb0f96b8a8--despicable-minions-funny-minion.jpg', + title='this is menu2', + text='description2', + actions=[ + PostbackTemplateAction( + label='postback2', + text='postback text2', + data='action=buy&itemid=2' + ), + MessageTemplateAction( + label='message2', + text='message text2' + ), + URITemplateAction( + label='uri2', + uri='https://i.pinimg.com/736x/48/bd/3f/48bd3f6e928d7cb4b8d499cb0f96b8a8--despicable-minions-funny-minion.jpg' + ) + ] + ) + ] + ) + + }) + command.set_template('TemplateMessage') diff --git a/src/middleware/confirm_template_middleware.py b/src/middleware/confirm_template_middleware.py new file mode 100644 index 0000000..ede2cff --- /dev/null +++ b/src/middleware/confirm_template_middleware.py @@ -0,0 +1,31 @@ +from linebot.models import ( + PostbackTemplateAction, MessageTemplateAction, ConfirmTemplate +) +from .middleware import Middleware + + +class ConfirmTemplateMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '5' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message({'alt_text': 'Confirm template', + 'template': ConfirmTemplate( + text='Are you sure?', + actions=[ + PostbackTemplateAction( + label='postback', + text='postback text', + data='action=buy&itemid=1' + ), + MessageTemplateAction( + label='message', + text='message text' + ) + ] + ) + }) + command.set_template('TemplateMessage') diff --git a/src/middleware/default_message_middleware.py b/src/middleware/default_message_middleware.py new file mode 100644 index 0000000..ca3fd16 --- /dev/null +++ b/src/middleware/default_message_middleware.py @@ -0,0 +1,14 @@ +from .middleware import Middleware + + +class DefaultMessageMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = 'commandDefault' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + message = "************\nPress Number for order\n1.TextMessage\n2.ImageMessage\n3.LocationMessage\n4.StickerMessage\n5.ConfirmTemplate\n6.ButtonTemplate\n7.CarouselTemplate\n************" + command.set_message(message) + command.set_template('TextMessage') diff --git a/src/middleware/hello_middleware.py b/src/middleware/hello_middleware.py new file mode 100644 index 0000000..c1b0319 --- /dev/null +++ b/src/middleware/hello_middleware.py @@ -0,0 +1,13 @@ +from .middleware import Middleware + + +class HelloMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '1' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message('Hello! World!!') + command.set_template('TextMessage') diff --git a/src/middleware/image_message_middleware.py b/src/middleware/image_message_middleware.py new file mode 100644 index 0000000..289d9bf --- /dev/null +++ b/src/middleware/image_message_middleware.py @@ -0,0 +1,14 @@ +from .middleware import Middleware + + +class ImageMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '2' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message({'original_content_url': 'https://i.pinimg.com/736x/48/bd/3f/48bd3f6e928d7cb4b8d499cb0f96b8a8--despicable-minions-funny-minion.jpg', + 'preview_image_url': 'https://i.pinimg.com/736x/48/bd/3f/48bd3f6e928d7cb4b8d499cb0f96b8a8--despicable-minions-funny-minion.jpg'}) + command.set_template('ImageMessage') diff --git a/src/middleware/location_message_middleware.py b/src/middleware/location_message_middleware.py new file mode 100644 index 0000000..20a2dbb --- /dev/null +++ b/src/middleware/location_message_middleware.py @@ -0,0 +1,16 @@ +from .middleware import Middleware + + +class LocationMessageMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '3' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message({'title': 'my location', + 'address': 'Tokyo', + 'latitude': '35.65910807942215', + 'longitude': '139.70372892916203'}) + command.set_template('LocationMessage') diff --git a/src/middleware/middleware.py b/src/middleware/middleware.py new file mode 100644 index 0000000..b084912 --- /dev/null +++ b/src/middleware/middleware.py @@ -0,0 +1,10 @@ +class Middleware(): + + def __init__(self, command): + self.do_next = True + + def next(self): + return self.do_next + + def execute(self, command): + pass diff --git a/src/middleware/sticker_message_middleware.py b/src/middleware/sticker_message_middleware.py new file mode 100644 index 0000000..bdc7928 --- /dev/null +++ b/src/middleware/sticker_message_middleware.py @@ -0,0 +1,14 @@ +from .middleware import Middleware + + +class StickerMessageMiddleware(Middleware): + + def __init__(self): + self.do_next = True + self.middleware_command = '4' + + def execute(self, command): + if(command.get_command() == self.middleware_command): + command.set_message({'package_id': '1', + 'sticker_id': '1'}) + command.set_template('StickerMessage') diff --git a/src/receiver.py b/src/receiver.py new file mode 100644 index 0000000..331e95f --- /dev/null +++ b/src/receiver.py @@ -0,0 +1,26 @@ +from .command.command_registry import CommandRegistry +from .command.command1 import Command1 +from .command.command2 import Command2 +from .command.command3 import Command3 +from .command.command4 import Command4 +from .command.command5 import Command5 +from .command.command6 import Command6 +from .command.command7 import Command7 +from .command.commandDefault import CommandDefault +from .command_bus import CommandBus + + +class Receiver(): + + def __init__(self, event): + self.event = event + command_registry = CommandRegistry(self.event) + command_registry.add_command(Command1()) + command_registry.add_command(Command2()) + command_registry.add_command(Command3()) + command_registry.add_command(Command4()) + command_registry.add_command(Command5()) + command_registry.add_command(Command6()) + command_registry.add_command(Command7()) + command_registry.add_command(CommandDefault()) + command_bus = CommandBus(command_registry.get_command())