def get_maker_profile(sender_id): from app.settings import FACEBOOK_TOKEN from bot.models import MakerProfile from bot.lib.utilities import create_file from bot.lib.maker import get_maker_id import requests import json r = requests.get("https://graph.facebook.com/v2.6/{0}".format(sender_id), params=dict( fields=['first_name', 'last_name', 'profile_pic'], access_token=FACEBOOK_TOKEN)) profile_data = json.loads(r.content) profile_picture = None if profile_data.get('profile_pic'): profile_picture = create_file(url=profile_data['profile_pic'], file_type='image') maker_profile, new = MakerProfile.objects.update_or_create( maker_id=get_maker_id(sender_id=sender_id), defaults=dict(first_name=profile_data.get('first_name'), last_name=profile_data.get('last_name'), timezone=profile_data.get('timezone'), gender=profile_data.get('gender'), locale=profile_data.get('locale'), profile_picture=profile_picture)) return sender_id
def process_menu_selection(sender_id, postback): from bot.lib.maker import update_maker, get_maker_id from common.facebook import send_message from bot.models import Project """""" context = dict() message_text = None conversation = dict() attachment = None if postback == "ADD_PROJECT_PAYLOAD": conversation = dict(name="create_project", stage="name_project") # TODO handle when user projects settings projects = Project.objects.filter(maker_id=get_maker_id( sender_id=sender_id)).filter(complete=True).exclude(finished=True) if projects.count() == 6: message_text = "Sorry it looks like you have max out your new project. You need to finish something before you can add anything new" else: message_text = "Great! What would you like to call this project?" elif postback == "UPDATE_PROJECT_PAYLOAD": conversation = dict(name="update_project_status", stage="project_selection") projects = Project.objects.filter(maker_id=get_maker_id( sender_id=sender_id)).filter(complete=True).exclude(finished=True) if projects.count() == 0: message_text = "It looks like you don't have any active projects. Add a project to get started!" conversation = dict(name="menu", stage="menu") elif projects.count() <= 2: attachment = format_project_carousel(projects=projects) elif projects.count() > 2: attachment = send_update_project(sender_id=sender_id) elif postback in ["ADD_PATTERN_PAYLOAD", "ADD_MATERIAL_PAYLOAD"]: conversation = dict(name="create_supplies", stage="add_image") context = dict(type=postback.split("_")[1].lower()) message_text = "Awesome! Please take a photo of the {0} to get started".format( context['type']) update_maker(sender_id=sender_id, conversation=conversation, context=context) send_message(sender_id=sender_id, text=message_text, attachment=attachment)
def respond(sender_id, message_text, attachment_type, attachment_url, postback, quick_reply, context): from bot.lib.maker import get_maker_id from bot.lib.project import create_project from bot.models import Pattern """Takes in ``sender_id``, ``message_text``= text,``context``= project id updates project and sends a reponse. :param str sender_id: The unique id created by facebook and the current facebook's sender's ID :param str message_text: Any text written by the send in the chat interface :param dict context: attributes sent between conversations :param str attachment_type: dentifies attachment type i.e photo (optional, defaults to None) :param str attachment_url: The location of the attachment (optional, defaults to None) :param str postback: a reponse sent from the user clicking a button (optional, defaults to None) :param str quick_reply: an automatic reply (optional, defaults to None) :returns: ``reponse``a dict with the next message to move the conversation, ``new_context``, and ``coverstation`` dict containing the next stage and task for the the bot """ project, created = create_project(sender_id=sender_id, name=message_text) new_context = dict() if created: new_context = dict(project_id=str(project.id)) response = dict( message_text="That's a great name. So what are you making?", quick_replies=[{ "content_type": "text", "title": "New Pattern", "payload": "ADD_PATTERN", }]) if Pattern.objects.filter(maker_id=get_maker_id( sender_id=sender_id)).count() > 0: response['quick_replies'].append({ "content_type": "text", "title": "Select Pattern", "payload": "SELECT_PATTERN", }) conversation = dict(name='create_project', stage='pattern_menu') else: response = dict( message_text= "It looks like you already have a project called {0}. What would you like to call this project?" .format(message_text)) conversation = dict(name='create_project', stage='name_project') return response, new_context, conversation
def respond(sender_id, message_text, attachment_type, attachment_url, postback, quick_reply, context): from bot.models import Pattern from bot.lib.maker import get_maker_id from .utilities import format_supply_carousel, send_patterns """Takes in ``sender_id``, ``message_text``= add or select, ``quick_reply`` = add or select ``context``= project id and updates project and sends a reponse. :param str sender_id: The unique id created by facebook and the current facebook's sender's ID :param str quick_reply: an automatic reply :param str message_text: Any text written in the chat interface :param dict context: attributes sent between conversations :param str attachment_type: dentifies attachment type i.e photo (optional, defaults to None) :param str attachment_url: The location of the attachment (optional, defaults to None) :param str postback: a reponse sent from the user clicking a button (optional, defaults to None) :returns: ``reponse``a dict with the next message to move the conversation ``new_context`` context project id, and ``coverstation`` dict containing the next stage and task for the the bot """ supply_type = 'pattern' action = 'add' if (quick_reply and 'select' in quick_reply.lower()) or ( message_text and 'select' in message_text.lower()): action = 'select' conversation = dict(name='create_project', stage='{0}_{1}'.format(action, supply_type)) new_context = context if action == 'select': maker_id = get_maker_id(sender_id=sender_id) patterns = Pattern.objects.filter(maker_id=maker_id) if patterns.count() <= 2: response = dict(attachment=format_supply_carousel( supply_query_set=patterns)) elif patterns.count() > 2: response = send_patterns(sender_id=sender_id) else: response = dict( message_text='Take a photo of your {0}'.format(supply_type)) return response, new_context, conversation
def update_project(request): from bot.models import Project from bot.lib.maker import get_maker_id from common.utilities import get_file_url """Generates all inprogress projects for the user, allowing them to select which one to update.""" maker_id = get_maker_id(request.GET.get('sender_id')) projects = Project.objects.filter(maker_id=maker_id).exclude( finished=True).filter(complete=True).prefetch_related( "tags").prefetch_related("patterns__files") # project name: str, project img: url, project id: str, project tags: str project_dicts = [] for project in projects: project_dict = dict( id=project.id, name=project.name, img_url=get_file_url(project.patterns.first().files.first()), tags=", ".join([i.name for i in project.tags.all()])) project_dicts.append(project_dict) return render(request, 'projects.html', context=dict(projects=project_dicts))
def select_supply(request): from bot.models import Pattern, Material from bot.lib.maker import get_maker_id from common.utilities import get_file_url """Generates gallery for the user, allowing them to select which supplies they want to use.""" supply_class = Pattern if "material" in request.path.lower(): supply_class = Material maker_id = get_maker_id(request.GET.get('sender_id')) supplies = supply_class.objects.filter( maker_id=maker_id).prefetch_related("tags").prefetch_related("files") supply_dicts = [] for supply in supplies: supply_dict = dict(id=supply.id, img_url=get_file_url(supply.files.first()), tags=", ".join([i.name for i in supply.tags.all()])) supply_dicts.append(supply_dict) return render(request, 'supplies.html', context=dict(supplies=supply_dicts))
def process_message(sender_id, message_text, quick_reply, postback, attachment_url, attachment_type): from common.facebook import send_message from bot.models import Maker from bot.lib.maker import get_maker_id, update_maker from bot.lib.conversation import load_conversation """Processes user input and responds with the next stage of the conversation. Function processes user input, loads the current conversation and validates the input before continuing. Bot responds with a prompt for valid input or continues the conversation. :param str sender_id: The unique id created by facebook and the current facebook's sender's ID :param str message_text: Any text written by the send in the chat interface :param str attachment_type: dentifies attachment type i.e photo (optional, defaults to None) :param str attachment_url: The location of the attachment (optional, defaults to None) :param str postback: a reponse sent from the user clicking a button (optional, defaults to None) :param str quick_reply: an automatic reply (optional, defaults to None) :returns: ``valid`` a boolean whether the message was valid """ send_message(sender_id=sender_id, action='mark_seen') maker = Maker.objects.prefetch_related( "conversation_stage__conversation").get(id=get_maker_id( sender_id=sender_id)) # Loads conversation by name. # #Conversations are located in bot/conversations/{conversation_name}/{stage_name}.py conversation = load_conversation( conversation_name=maker.conversation_stage.conversation.name, stage_name=maker.conversation_stage.name) valid, failure_response = conversation.validate( sender_id=sender_id, message_text=message_text, quick_reply=quick_reply, postback=postback, attachment_type=attachment_type) if not valid: send_message(sender_id=sender_id, text=failure_response.get('message_text'), buttons=failure_response.get('buttons'), attachment=failure_response.get('attachment'), quick_replies=failure_response.get('quick_replies')) else: # Starts typing so that the user can see that the bot is processing. send_message(sender_id=sender_id, action='typing_on') response, context, next_conversation = conversation.respond( sender_id=sender_id, message_text=message_text, quick_reply=quick_reply, postback=postback, attachment_type=attachment_type, attachment_url=attachment_url, context=maker.context) r = send_message(sender_id=sender_id, text=response.get('message_text'), buttons=response.get('buttons'), attachment=response.get('attachment'), quick_replies=response.get('quick_replies')) # Sets the next stage of the conversation and persists and conversation context. update_maker(sender_id=sender_id, context=context, conversation=next_conversation) return valid