示例#1
0
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
示例#2
0
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)
示例#3
0
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
示例#4
0
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
示例#5
0
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))
示例#6
0
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))
示例#7
0
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