def get_sample_suggestions(): """Creates a list of sample suggestions that includes a suggested reply. Returns: A :list: A list of sample BusinessMessagesSuggestions. """ return [ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='Sample Chip', postbackData='sample_chip')), BusinessMessagesSuggestion(action=BusinessMessagesSuggestedAction( text='URL Action', postbackData='url_action', openUrlAction=BusinessMessagesOpenUrlAction( url='https://www.google.com'))), BusinessMessagesSuggestion(action=BusinessMessagesSuggestedAction( text='Dial Action', postbackData='dial_action', dialAction=BusinessMessagesDialAction( phoneNumber='+12223334444'))), ]
def send_shopping_cart_empty_message(conv): ''' Inform the user that their shopping cart is empty. Args: conv (Conversation): The conversation object tied to the user ''' message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=MSG_EMPTY_CART, suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_FOOD_MENU, postbackData=CMD_FOOD_MENU)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_DRINKS_MENU, postbackData=CMD_DRINK_MENU)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_PENDING_ORDERS, postbackData=CMD_SHOW_PENDING_PICKUP)), ]) send_message(message_obj, conv.id)
def send_abandoned_cart_message(conv): ''' Sends the message received from the user back to the user. Args: message (str): The message text received from the user. conversation_id (str): The unique id for this user and agent. ''' message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=MSG_CART_NOW_EMPTY, suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_FOOD_MENU, postbackData=CMD_FOOD_MENU)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_CHECK_PENDING_ORDERS, postbackData=CMD_SHOW_PENDING_PICKUP)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_PAST_PURCHASES, postbackData=CMD_SHOW_PURCHASES)), ]) send_message(message_obj, conv.id)
def send_item_added_to_cart(conv, item): ''' Inform the user that they've added an item to the cart. Args: conv (Conversation): The conversation object tied to the user item (Item): The item the user wants to add to their cart ''' message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=f"You've added an item to your cart: {item.name}", suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SEE_CART, postbackData=CMD_SHOW_CART)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SEE_CART_BREAKDOWN, postbackData=CMD_CART_BREAKDOWN)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_FOOD_MENU, postbackData=CMD_FOOD_MENU)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_DRINKS_MENU, postbackData=CMD_DRINK_MENU)), ]) send_message(message_obj, conv.id)
def get_cart_carousel(cart_items): ''' A function that returns the items in the shopping cart in a carousel. ''' card_content = [] for cart_entity in cart_items: card_content.append( BusinessMessagesCardContent( title=cart_entity.item.name, description=f'Quantity: {cart_entity.quantity}', suggestions=[ BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text='➕', postbackData= f'{CMD_ADD_TO_CART}-{cart_entity.item.id}')), BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text='➖', postbackData= f'remove_from_cart-{cart_entity.item.id}')), BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text=MSG_REMOVE_ALL, postbackData= f'remove_all_from_cart-{cart_entity.item.id}')), ], media=BusinessMessagesMedia( height=BusinessMessagesMedia.HeightValueValuesEnum.MEDIUM, contentInfo=BusinessMessagesContentInfo( fileUrl=cart_entity.item.image_url, forceRefresh=False)))) return BusinessMessagesCarouselCard( cardContents=card_content, cardWidth=BusinessMessagesCarouselCard.CardWidthValueValuesEnum.MEDIUM)
def send_cart_breakdown_message(conv): ''' This function sends a textual representation ''' cart = conv.shopping_cart shopped_items = ShoppedItem.objects.filter(cart=cart) if len(shopped_items) == 0: cart_breakdown = MSG_CART_NOW_EMPTY else: cart_breakdown = "Here's your cart breakdown:\n\n" total_price = 0 for shopped_item in shopped_items: total_price = total_price + shopped_item.item.price * shopped_item.quantity cart_breakdown = cart_breakdown + f'''{shopped_item.item.name}\n Quantity: {shopped_item.quantity}\n Price: ${shopped_item.item.price * shopped_item.quantity}\n\n''' cart_breakdown = cart_breakdown + f'-----\nSubtotal Price: ${total_price}' message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=cart_breakdown, suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_PURCHASE_CART, postbackData=CMD_PURCHASE_CART)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_CHECK_PENDING_ORDERS, postbackData=CMD_SHOW_PENDING_PICKUP)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_ABANDON_CART, postbackData=CMD_ABANDON_CART)), ]) send_message(message_obj, conv.id)
def send_proceed_to_payment_message(conv): ''' Send an openUrlAction to open the webpage that sends the user to Stripe for payment. Args: conv (Conversation): The conversation object tied to the user ''' message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text='''Great! Thanks for confirming. Proceed to checkout and we'll let you know when your order is ready for pickup!''', suggestions=[ BusinessMessagesSuggestion(action=BusinessMessagesSuggestedAction( text=MSG_PURCHASE, postbackData=MSG_PURCHASE, openUrlAction=BusinessMessagesOpenUrlAction( url=f'{DOMAIN}/bopis/checkout/{conv.id}'))), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_ABANDON_CART, postbackData=CMD_ABANDON_CART)), ]) send_message(message_obj, conv.id)
def send_shopping_cart_total_price(conversation_id): """Sends shopping cart price to user through Business Messages. Args: conversation_id (str): The unique id for this user and agent. """ cart_price = get_cart_price(conversation_id) message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=f'Your cart\'s total price is ${cart_price}.', suggestions=[ BusinessMessagesSuggestion(action=BusinessMessagesSuggestedAction( text='Checkout', postbackData='checkout', openUrlAction=BusinessMessagesOpenUrlAction( url=f'{YOUR_DOMAIN}/checkout/{conversation_id}'))), ]) send_message(message_obj, conversation_id)
def send_online_shopping_info_message(conversation_id): ''' Sends a rich card with online shopping info to the user. Args: conversation_id (str): The unique id for this user and agent. ''' fallback_text = ('Online shopping will be available soon!') rich_card = BusinessMessagesRichCard( standaloneCard= BusinessMessagesStandaloneCard(cardContent=BusinessMessagesCardContent( title='Online shopping info!', description= 'Thanks for your business, we are located in SF near the Golden Gate Bridge. Online shopping is not yet available, please check back with us in a few days.', suggestions=[], media=BusinessMessagesMedia( height=BusinessMessagesMedia.HeightValueValuesEnum.MEDIUM, contentInfo=BusinessMessagesContentInfo( fileUrl=SAMPLE_IMAGES[4], forceRefresh=False))))) message_obj = BusinessMessagesMessage(messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, richCard=rich_card, fallback=fallback_text) send_message(message_obj, conversation_id) message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text='Let us know how else we can help you:', fallback='Please let us know how else we can help you.', suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='Business hours', postbackData='business-hours-inquiry')), ]) send_message(message_obj, conversation_id)
def checkout_failure(request): ''' User has failed to checkout and the Stripe callback sends the user to a notice. Args: request (HttpRequest): The request object that django passes to the function Returns: Returns a template filled with contextual data to the request ''' conversation_id = request.GET.get("conversation_id") message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=MSG_COULD_NOT_PROCESS, suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text=MSG_TRY_AGAIN, postbackData=CMD_RESET_PICKUP_DETAILS)), ]) send_message(message_obj, conversation_id) return render(request, 'bopis/complete.html')
def payment_success(request, conversation_id): """Sends a notification to the user prompting them back into the conversation. Args: request (HttpRequest): Incoming Django request object conversation_id (str): The unique id for this user and agent. Returns: Obj (HttpResponse): Returns an HTTPResponse to the browser """ message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='Check on order', postbackData='check-order')), ], text='Awesome it looks like we\'ve received you\'re payment.') send_message(message_obj, conversation_id) return render(request, 'bopis/success.html')
def send_message_with_business_hours(conversation_id): ''' Sends a message containing hours of operation for the business. Args: conversation_id (str): The unique id for this user and agent. ''' message = '''Thanks for contacting us! The hours for the store are:\n MON 8am - 8pm\n TUE 8am - 8pm\n WED 8am - 8pm\n THU 8am - 8pm\n FRI 8am - 8pm\n SAT 8am - 8pm\n SUN 8am - 8pm ''' message_obj = BusinessMessagesMessage(messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=message) send_message(message_obj, conversation_id) message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text='Let us know how else we can help you:', fallback='Please let us know how else we can help you.', suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='Can I purchase online?', postbackData='online-shopping-inquiry')), ]) send_message(message_obj, conversation_id)
def send_shopping_cart(conv): ''' Send the user their shopping cart. ''' cart_items = ShoppedItem.objects.filter(cart=conv.shopping_cart) if not conv.shopping_cart or len(cart_items) == 0: message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=MSG_EMPTY_CART, suggestions=[ BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_FOOD_MENU, postbackData=CMD_FOOD_MENU)), BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text=MSG_SHOW_DRINKS_MENU, postbackData=CMD_DRINK_MENU)), BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text=MSG_PENDING_ORDERS, postbackData=CMD_SHOW_PENDING_PICKUP)), ]) send_message(message_obj, conv.id) elif len(cart_items) == 1: fallback_text = ( f'Your shopping cart contains a {cart_items[0].item.name}') rich_card = BusinessMessagesRichCard( standaloneCard=BusinessMessagesStandaloneCard( cardContent=BusinessMessagesCardContent( title=cart_items[0].item.name, description=f'Quantity: {cart_items[0].quantity}', suggestions=[], media=BusinessMessagesMedia( height=BusinessMessagesMedia.HeightValueValuesEnum. MEDIUM, contentInfo=BusinessMessagesContentInfo( fileUrl=cart_items[0].item.image_url, forceRefresh=False))))) message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, richCard=rich_card, fallback=fallback_text) send_message(message_obj, conv.id) message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=f'''The total value of your shopping cart is ${cart_items[0].item.price * cart_items[0].quantity}.''', suggestions=get_cart_suggestions()) send_message(message_obj, conv.id) else: rich_card = BusinessMessagesRichCard( carouselCard=get_cart_carousel(cart_items)) # Construct a fallback text for devices that do not support carousels. fallback_text = '' for card_content in rich_card.carouselCard.cardContents: fallback_text += ( card_content.title + '\n\n' + card_content.description + '\n\n' + card_content.media.contentInfo.fileUrl + '\n---------------------------------------------\n\n') message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, richCard=rich_card, fallback=fallback_text) send_message(message_obj, conv.id) total_price = 0 for cart_item in cart_items: total_price = total_price + cart_item.item.price * cart_item.quantity message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=f'The total value of your shopping cart is ${total_price}.', suggestions=get_cart_suggestions()) send_message(message_obj, conv.id)
def send_shopping_cart(conversation_id): """Sends a shopping cart to the user as a rich card carousel. Args: conversation_id (str): The unique id for this user and agent. """ credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_LOCATION) # Retrieve the inventory data inventory = get_inventory_data() # Pull the data from Google Datastore client = datastore.Client(credentials=credentials) key = client.key('ShoppingCart', conversation_id) result = client.get(key) shopping_cart_suggestions = [ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='See total price', postbackData='show-cart-price')), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='Empty the cart', postbackData='empty-cart')), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='See the menu', postbackData=CMD_SHOW_PRODUCT_CATALOG)), ] if len(result.items()) == 0: message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text='There are no items in your shopping cart.', suggestions=shopping_cart_suggestions) send_message(message_obj, conversation_id) elif len(result.items()) == 1: for product_name, quantity in result.items(): product_id = get_id_by_product_name(product_name) fallback_text = ('You have one type of item in the shopping cart') rich_card = BusinessMessagesRichCard( standaloneCard=BusinessMessagesStandaloneCard( cardContent=BusinessMessagesCardContent( title=product_name, description=f'{quantity} in cart.', suggestions=[ BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text='Remove one', postbackData='{' + f'"action":"{CMD_DEL_ITEM}","item_name":"{product_id}"' + '}')) ], media=BusinessMessagesMedia( height=BusinessMessagesMedia.HeightValueValuesEnum. MEDIUM, contentInfo=BusinessMessagesContentInfo( fileUrl=inventory['food'][product_id] ['image_url'], forceRefresh=False))))) message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, richCard=rich_card, suggestions=shopping_cart_suggestions, fallback=fallback_text) send_message(message_obj, conversation_id) else: cart_carousel_items = [] # Iterate through the cart and generate a carousel of items for product_name, quantity in result.items(): product_id = get_id_by_product_name(product_name) cart_carousel_items.append( BusinessMessagesCardContent( title=product_name, description=f'{quantity} in cart.', suggestions=[ BusinessMessagesSuggestion( reply=BusinessMessagesSuggestedReply( text='Remove one', postbackData='{' + f'"action":"{CMD_DEL_ITEM}","item_name":"{product_id}"' + '}')) ], media=BusinessMessagesMedia( height=BusinessMessagesMedia.HeightValueValuesEnum. MEDIUM, contentInfo=BusinessMessagesContentInfo( fileUrl=inventory['food'][product_id]['image_url'], forceRefresh=False)))) rich_card = BusinessMessagesRichCard( carouselCard=BusinessMessagesCarouselCard( cardContents=cart_carousel_items, cardWidth=BusinessMessagesCarouselCard. CardWidthValueValuesEnum.MEDIUM)) fallback_text = '' # Construct a fallback text for devices that do not support carousels for card_content in rich_card.carouselCard.cardContents: fallback_text += ( card_content.title + '\n\n' + card_content.description + '\n\n' + card_content.media.contentInfo.fileUrl + '\n---------------------------------------------\n\n') message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, richCard=rich_card, suggestions=shopping_cart_suggestions, fallback=fallback_text, ) send_message(message_obj, conversation_id)
def update_shopping_cart(conversation_id, message): """Updates the shopping cart stored in Google Datastore. Args: conversation_id (str): The unique id for this user and agent. message (str): The message containing whether to add or delete an item. """ credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_LOCATION) inventory = get_inventory_data() cart_request = json.loads(message) cart_cmd = cart_request["action"] cart_item = cart_request["item_name"] item_name = inventory['food'][int(cart_item)]['name'] client = datastore.Client(credentials=credentials) key = client.key('ShoppingCart', conversation_id) entity = datastore.Entity(key=key) result = client.get(key) if result is None: if cart_cmd == CMD_ADD_ITEM: entity.update({item_name: 1}) elif cart_cmd == CMD_DEL_ITEM: # The user is trying to delete an item from an empty cart. Pass and skip pass else: if cart_cmd == CMD_ADD_ITEM: if result.get(item_name) is None: result[item_name] = 1 else: result[item_name] = result[item_name] + 1 elif cart_cmd == CMD_DEL_ITEM: if result.get(item_name) is None: # The user is trying to remove an item that's no in the shopping cart. # Pass and skip pass elif result[item_name] - 1 > 0: result[item_name] = result[item_name] - 1 else: del result[item_name] entity.update(result) client.put(entity) if cart_cmd == CMD_ADD_ITEM: message = 'Great! You\'ve added an item to the cart.' else: message = 'You\'ve removed an item from the cart.' message_obj = BusinessMessagesMessage( messageId=str(uuid.uuid4().int), representative=BOT_REPRESENTATIVE, text=message, suggestions=[ BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='Review shopping cart', postbackData=CMD_SHOW_CART)), BusinessMessagesSuggestion(reply=BusinessMessagesSuggestedReply( text='See menu again', postbackData=CMD_SHOW_PRODUCT_CATALOG)), ]) send_message(message_obj, conversation_id)