├── lambda └── py │ ├── requirements.txt │ └── lambda_function.py ├── README.md ├── models └── en-US.json ├── .gitignore └── LICENSE /lambda/py/requirements.txt: -------------------------------------------------------------------------------- 1 | ask-sdk-core 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alexa Kosher Pickup Lines skill 2 | -------------------------------------------------------------------------------- /models/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "interactionModel": { 3 | "languageModel": { 4 | "invocationName": "kosher pickup lines", 5 | "intents": [ 6 | { 7 | "name": "AMAZON.CancelIntent", 8 | "samples": [] 9 | }, 10 | { 11 | "name": "AMAZON.HelpIntent", 12 | "samples": [] 13 | }, 14 | { 15 | "name": "AMAZON.StopIntent", 16 | "samples": [] 17 | }, 18 | { 19 | "name": "AMAZON.NavigateHomeIntent", 20 | "samples": [] 21 | }, 22 | { 23 | "name": "AMAZON.FallbackIntent", 24 | "samples": [] 25 | }, 26 | { 27 | "name": "GetNewPickupLineIntent", 28 | "slots": [], 29 | "samples": [ 30 | "a line", 31 | "a pickup line", 32 | "tell me a line", 33 | "tell me a pickup line", 34 | "give me a line", 35 | "give me a pickup line", 36 | "tell me kosher pickup", 37 | "tell me a kosher pickup", 38 | "give me kosher pickup", 39 | "give me a kosher pickup", 40 | "give me some lines", 41 | "give me some pickup lines", 42 | "tell me kosher pickup lines", 43 | "give me kosher pickup lines" 44 | ] 45 | } 46 | ], 47 | "types": [] 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VS Code settings 2 | .vscode* 3 | 4 | # Helpfer python files 5 | create* 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | *.py[cod] 10 | *$py.class 11 | 12 | # C extensions 13 | *.so 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # celery beat schedule file 90 | celerybeat-schedule 91 | 92 | # SageMath parsed files 93 | *.sage.py 94 | 95 | # Environments 96 | .env 97 | .venv 98 | env/ 99 | venv/ 100 | ENV/ 101 | env.bak/ 102 | venv.bak/ 103 | 104 | # Spyder project settings 105 | .spyderproject 106 | .spyproject 107 | 108 | # Rope project settings 109 | .ropeproject 110 | 111 | # mkdocs documentation 112 | /site 113 | 114 | # mypy 115 | .mypy_cache/ 116 | .dmypy.json 117 | dmypy.json 118 | 119 | # Pyre type checker 120 | .pyre/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Amazon Software License 1.0 2 | 3 | This Amazon Software License ("License") governs your use, reproduction, and 4 | distribution of the accompanying software as specified below. 5 | 6 | 1. Definitions 7 | 8 | "Licensor" means any person or entity that distributes its Work. 9 | 10 | "Software" means the original work of authorship made available under this 11 | License. 12 | 13 | "Work" means the Software and any additions to or derivative works of the 14 | Software that are made available under this License. 15 | 16 | The terms "reproduce," "reproduction," "derivative works," and 17 | "distribution" have the meaning as provided under U.S. copyright law; 18 | provided, however, that for the purposes of this License, derivative works 19 | shall not include works that remain separable from, or merely link (or bind 20 | by name) to the interfaces of, the Work. 21 | 22 | Works, including the Software, are "made available" under this License by 23 | including in or with the Work either (a) a copyright notice referencing the 24 | applicability of this License to the Work, or (b) a copy of this License. 25 | 26 | 2. License Grants 27 | 28 | 2.1 Copyright Grant. Subject to the terms and conditions of this License, 29 | each Licensor grants to you a perpetual, worldwide, non-exclusive, 30 | royalty-free, copyright license to reproduce, prepare derivative works of, 31 | publicly display, publicly perform, sublicense and distribute its Work and 32 | any resulting derivative works in any form. 33 | 34 | 2.2 Patent Grant. Subject to the terms and conditions of this License, each 35 | Licensor grants to you a perpetual, worldwide, non-exclusive, royalty-free 36 | patent license to make, have made, use, sell, offer for sale, import, and 37 | otherwise transfer its Work, in whole or in part. The foregoing license 38 | applies only to the patent claims licensable by Licensor that would be 39 | infringed by Licensor's Work (or portion thereof) individually and 40 | excluding any combinations with any other materials or technology. 41 | 42 | 3. Limitations 43 | 44 | 3.1 Redistribution. You may reproduce or distribute the Work only if 45 | (a) you do so under this License, (b) you include a complete copy of this 46 | License with your distribution, and (c) you retain without modification 47 | any copyright, patent, trademark, or attribution notices that are present 48 | in the Work. 49 | 50 | 3.2 Derivative Works. You may specify that additional or different terms 51 | apply to the use, reproduction, and distribution of your derivative works 52 | of the Work ("Your Terms") only if (a) Your Terms provide that the use 53 | limitation in Section 3.3 applies to your derivative works, and (b) you 54 | identify the specific derivative works that are subject to Your Terms. 55 | Notwithstanding Your Terms, this License (including the redistribution 56 | requirements in Section 3.1) will continue to apply to the Work itself. 57 | 58 | 3.3 Use Limitation. The Work and any derivative works thereof only may be 59 | used or intended for use with the web services, computing platforms or 60 | applications provided by Amazon.com, Inc. or its affiliates, including 61 | Amazon Web Services, Inc. 62 | 63 | 3.4 Patent Claims. If you bring or threaten to bring a patent claim against 64 | any Licensor (including any claim, cross-claim or counterclaim in a 65 | lawsuit) to enforce any patents that you allege are infringed by any Work, 66 | then your rights under this License from such Licensor (including the 67 | grants in Sections 2.1 and 2.2) will terminate immediately. 68 | 69 | 3.5 Trademarks. This License does not grant any rights to use any 70 | Licensor's or its affiliates' names, logos, or trademarks, except as 71 | necessary to reproduce the notices described in this License. 72 | 73 | 3.6 Termination. If you violate any term of this License, then your rights 74 | under this License (including the grants in Sections 2.1 and 2.2) will 75 | terminate immediately. 76 | 77 | 4. Disclaimer of Warranty. 78 | 79 | THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 80 | EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF 81 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR 82 | NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER 83 | THIS LICENSE. SOME STATES' CONSUMER LAWS DO NOT ALLOW EXCLUSION OF AN 84 | IMPLIED WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO YOU. 85 | 86 | 5. Limitation of Liability. 87 | 88 | EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL 89 | THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE 90 | SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, 91 | INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR 92 | RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK (INCLUDING 93 | BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS 94 | OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER COMM ERCIAL DAMAGES 95 | OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF 96 | SUCH DAMAGES. 97 | -------------------------------------------------------------------------------- /lambda/py/lambda_function.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Kosher pickup lines app.""" 3 | 4 | import random 5 | import logging 6 | 7 | from ask_sdk_core.skill_builder import SkillBuilder 8 | from ask_sdk_core.dispatch_components import ( 9 | AbstractRequestHandler, AbstractExceptionHandler, 10 | AbstractRequestInterceptor, AbstractResponseInterceptor) 11 | from ask_sdk_core.utils import is_request_type, is_intent_name 12 | from ask_sdk_core.handler_input import HandlerInput 13 | 14 | from ask_sdk_model.ui import SimpleCard 15 | from ask_sdk_model import Response 16 | 17 | 18 | # ========================================================================================================================================= 19 | # TODO: The items below this comment need your attention. 20 | # ========================================================================================================================================= 21 | SKILL_NAME = "Kosher Pickup Lines" 22 | GET_LINE_MESSAGE = "Here's your pickup line: " 23 | HELP_MESSAGE = "You can say tell me a pickup line, or, you can say exit... What can I help you with?" 24 | HELP_REPROMPT = "What can I help you with?" 25 | STOP_MESSAGE = "Goodbye!" 26 | FALLBACK_MESSAGE = "The Kosher pickup lines skill can't help you with that. It can help you with pickup lines if you say tell me a pickup line. What can I help you with?" 27 | FALLBACK_REPROMPT = 'What can I help you with?' 28 | EXCEPTION_MESSAGE = "Sorry. I cannot help you with that." 29 | 30 | 31 | data = '''You had me at shabbat shalom. 32 | Hey baby, I'll be your MANishewitz. 33 | Pray here often? 34 | Would you light my shabbas candles? 35 | That's a nice looking kipah. it would look even better on my floor tomorrow morning. 36 | I'll take the rest out of your day of rest. 37 | I put the syn in synagogue. 38 | Excuse me ladies, would you like to help me make a quadruple mitzvah? 39 | You must not be shomer shabbas, because you just turned me on. 40 | Kiss me, I'm Kosher. 41 | Eat me, I'm Kosher. 42 | Want to find out how salty my matzoh balls are? 43 | Is that a siddur in your pocket, or are you just happy to see me? 44 | Are you my prize for finding the Afikomen? 45 | Is that the afikoman in your pants or are you just happy to see me? 46 | I'll give you a burning bush. 47 | Do you want something to atone for on Yom Kippur? 48 | I'd like to dip my apple in your honey 49 | I've got a tekiah gedolah for you baby 50 | Would you like to blow my shofar? 51 | Nice Hanukkah bush. 52 | Wanna play spin the dreidel? 53 | Is that sour cream on your latke or were you just happy to see me? 54 | All I want for Christmas is Jew 55 | Hey Rabbi, you had me at "please rise" 56 | Hey baby, wanna shake my lulav? 57 | Is there an afikomen in your pocket, or are you just happy to see me? 58 | Please give me some maror of that gefilte fish. 59 | My kitchen is totally kosher for Passover. 60 | I have two sets of dishes. 61 | I couldn't help noticing that shank bone on your plate. 62 | Why don't you come over and I'll SHOW you what makes this night different from all other nights. 63 | I make a great matzah brie in the morning 64 | I'll show you my charoset recipe if you show me yours 65 | Hey baby, let's make a Hanukkah miracle and see if I can last 8 nights! 66 | I'll show you my Christmas tree if you show me your Hanukkah bush! 67 | Just meeting you made me want to break a glass. 68 | Hey baby, I wanna see your Shabbat ShalOm face!'''.split('\n') 69 | 70 | 71 | # ========================================================================================================================================= 72 | # Editing anything below this line might break your skill. 73 | # ========================================================================================================================================= 74 | 75 | sb = SkillBuilder() 76 | logger = logging.getLogger(__name__) 77 | logger.setLevel(logging.DEBUG) 78 | 79 | 80 | # Built-in Intent Handlers 81 | class GetNewPickupLineHandler(AbstractRequestHandler): 82 | """Handler for Skill Launch and GetNewPickupLine Intent.""" 83 | def can_handle(self, handler_input): 84 | # type: (HandlerInput) -> bool 85 | return (is_request_type("LaunchRequest")(handler_input) or 86 | is_intent_name("GetNewPickupLineIntent")(handler_input)) 87 | 88 | def handle(self, handler_input): 89 | # type: (HandlerInput) -> Response 90 | logger.info("In GetNewPickupLineHandler") 91 | 92 | random_line = random.choice(data) 93 | speech = GET_LINE_MESSAGE + random_line 94 | 95 | handler_input.response_builder.speak(speech).set_card( 96 | SimpleCard(SKILL_NAME, random_line)) 97 | return handler_input.response_builder.response 98 | 99 | 100 | class HelpIntentHandler(AbstractRequestHandler): 101 | """Handler for Help Intent.""" 102 | def can_handle(self, handler_input): 103 | # type: (HandlerInput) -> bool 104 | return is_intent_name("AMAZON.HelpIntent")(handler_input) 105 | 106 | def handle(self, handler_input): 107 | # type: (HandlerInput) -> Response 108 | logger.info("In HelpIntentHandler") 109 | 110 | handler_input.response_builder.speak(HELP_MESSAGE).ask( 111 | HELP_REPROMPT).set_card(SimpleCard( 112 | SKILL_NAME, HELP_MESSAGE)) 113 | return handler_input.response_builder.response 114 | 115 | 116 | class CancelOrStopIntentHandler(AbstractRequestHandler): 117 | """Single handler for Cancel and Stop Intent.""" 118 | def can_handle(self, handler_input): 119 | # type: (HandlerInput) -> bool 120 | return (is_intent_name("AMAZON.CancelIntent")(handler_input) or 121 | is_intent_name("AMAZON.StopIntent")(handler_input)) 122 | 123 | def handle(self, handler_input): 124 | # type: (HandlerInput) -> Response 125 | logger.info("In CancelOrStopIntentHandler") 126 | 127 | handler_input.response_builder.speak(STOP_MESSAGE) 128 | return handler_input.response_builder.response 129 | 130 | 131 | class FallbackIntentHandler(AbstractRequestHandler): 132 | """Handler for Fallback Intent. 133 | 134 | AMAZON.FallbackIntent is only available in en-US locale. 135 | This handler will not be triggered except in that locale, 136 | so it is safe to deploy on any locale. 137 | """ 138 | def can_handle(self, handler_input): 139 | # type: (HandlerInput) -> bool 140 | return is_intent_name("AMAZON.FallbackIntent")(handler_input) 141 | 142 | def handle(self, handler_input): 143 | # type: (HandlerInput) -> Response 144 | logger.info("In FallbackIntentHandler") 145 | 146 | handler_input.response_builder.speak(FALLBACK_MESSAGE).ask( 147 | FALLBACK_REPROMPT) 148 | return handler_input.response_builder.response 149 | 150 | 151 | class SessionEndedRequestHandler(AbstractRequestHandler): 152 | """Handler for Session End.""" 153 | def can_handle(self, handler_input): 154 | # type: (HandlerInput) -> bool 155 | return is_request_type("SessionEndedRequest")(handler_input) 156 | 157 | def handle(self, handler_input): 158 | # type: (HandlerInput) -> Response 159 | logger.info("In SessionEndedRequestHandler") 160 | 161 | logger.info("Session ended reason: {}".format( 162 | handler_input.request_envelope.request.reason)) 163 | return handler_input.response_builder.response 164 | 165 | 166 | # Exception Handler 167 | class CatchAllExceptionHandler(AbstractExceptionHandler): 168 | """Catch all exception handler, log exception and 169 | respond with custom message. 170 | """ 171 | def can_handle(self, handler_input, exception): 172 | # type: (HandlerInput, Exception) -> bool 173 | return True 174 | 175 | def handle(self, handler_input, exception): 176 | # type: (HandlerInput, Exception) -> Response 177 | logger.info("In CatchAllExceptionHandler") 178 | logger.error(exception, exc_info=True) 179 | 180 | handler_input.response_builder.speak(EXCEPTION_MESSAGE).ask( 181 | HELP_REPROMPT) 182 | 183 | return handler_input.response_builder.response 184 | 185 | 186 | # Request and Response loggers 187 | class RequestLogger(AbstractRequestInterceptor): 188 | """Log the alexa requests.""" 189 | def process(self, handler_input): 190 | # type: (HandlerInput) -> None 191 | logger.debug("Alexa Request: {}".format( 192 | handler_input.request_envelope.request)) 193 | 194 | 195 | class ResponseLogger(AbstractResponseInterceptor): 196 | """Log the alexa responses.""" 197 | def process(self, handler_input, response): 198 | # type: (HandlerInput, Response) -> None 199 | logger.debug("Alexa Response: {}".format(response)) 200 | 201 | 202 | # Register intent handlers 203 | sb.add_request_handler(GetNewPickupLineHandler()) 204 | sb.add_request_handler(HelpIntentHandler()) 205 | sb.add_request_handler(CancelOrStopIntentHandler()) 206 | sb.add_request_handler(FallbackIntentHandler()) 207 | sb.add_request_handler(SessionEndedRequestHandler()) 208 | 209 | # Register exception handlers 210 | sb.add_exception_handler(CatchAllExceptionHandler()) 211 | 212 | # TODO: Uncomment the following lines of code for request, response logs. 213 | # sb.add_global_request_interceptor(RequestLogger()) 214 | # sb.add_global_response_interceptor(ResponseLogger()) 215 | 216 | # Handler name that is used on AWS lambda 217 | lambda_handler = sb.lambda_handler() 218 | --------------------------------------------------------------------------------