Search the Web for Free Using Messenger and Python

3 min read
Search the Web for Free Using Messenger and Python
FreeSearch is now owned by BeeStripe LLC

A friend of mine sent me a link about Free Web Search wherein you can do web searches on Facebook Messenger using free data. I was amazed by the creator's idea. He even started a crowdfunding for it. However, as a software developer, I had to disagree with the figures. It is free for the users but not for the maintainer. The operational cost is too high that I had to hop in and create my own version with virtually zero cost.

I am using an AWS Free Tier account so I don't have to pay for the hosting for a year.


Creating a Facebook application

The idea requires integration to the Facebook Messenger. We will be building a chatbot. In this blog, you will learn the basics of building a Messenger chatbot.

You can read the official Messenger Platform Quick Start Tutorial here.

Sign up for a Facebook developer account.

Sign in, click My Apps and click Add New App.

Enter Display Name and Contact Email and click Create APP ID.

Select Get Started with the Pages API and click Confirm.

Fill up the following details and click Save Changes:

  • Privacy Policy URL
  • Terms of Service URL
  • App Icon
  • Business Use

These details are required for App Review if you want to release your chatbot to the public. Click Show button and take note of the App Secret. We will be using the App Secret later to validate if webhook requests really came from facebook.

On the left side of the dashboard, find PRODUCTS and click the + button.

Find Messenger and click Set Up.

In order to generate an access token, we are required to create a Facebook Page. Click Create a new page.

We can select Business or Brand but for this project, I selected Community or Public Figure. Enter the Page Name, select Category and click Continue.

From the page dashboard, click Settings and click Messenger Platform.

Select Primary Receiver from Role column.

Back to the Token Generation section from developer dashboard, select the created page and take note of the Page Access Token.


Creating a Flask application

For our Messenger chatbot, we will be using Flask on AWS Elastic Beanstalk. In the code below, I used Flask blueprints. To be able to interact with Messenger, we need to initiate calls to the Facebook Graph API.

For the searches, I used DuckDuckGo Instant Answer API instead of using Google Custom Search Engine since it is free.

Save the App Secret we obtained to the environment variable FB_APP_SECRET.

Lastly save the Page Access Token that we got from the Token Verification section to the environment variable FB_ACCESS_TOKEN. Generate your own Verify Token and save it to the environment variable FB_VERIFY_TOKEN.

If you want to know how to setup Flask on AWS Elastic Beanstalk, read my previous blog here.

import json
import os
import time

import requests
from flask import Blueprint, request

search = Blueprint('search', __name__, static_folder='static', template_folder='templates')
FB_GRAPH_URL = 'https://graph.facebook.com'
FB_GRAPH_VERSION = 'v3.2'


@search.route('/webhook', methods=['GET', 'POST'])
def webhook():
    header_signature = request.headers.get('X-Hub-Signature')  # type: str
    if header_signature is None:
        abort(403)
    sha_name, signature = header_signature.split('=', 2)
    if sha_name != 'sha1':
        abort(501)
    mac = hmac.new(os.getenv('FB_APP_SECRET').encode('utf-8'), msg=request.data, digestmod='sha1')
    if not hmac.compare_digest(mac.hexdigest(), signature):
        abort(403)
    if request.method == 'GET':
        if request.args.get('hub.verify_token') == os.getenv('FB_VERIFY_TOKEN'):
            return request.args.get('hub.challenge')
        return ''
    message_entries = json.loads(request.data.decode('utf8'))['entry']
    current_app.logger.info(message_entries)
    for entry in message_entries:
        for message in entry['messaging']:
            if 'message' in message:
                try:
                    results = duckduckgo(message['message']['text'])
                    for result in results:
                        send_text(message['sender']['id'], result)
                        time.sleep(1)  # let's respect DuckDuckGo rate limiting
                finally:
                    pass
            elif 'postback' in message:
                if message['postback']['payload'] == 'GET_STARTED':
                    send_text(message['sender']['id'], 'What do you want to search?')
    return ''


def send_text(recipient, message):
    try:
        requests.post(
            f'{FB_GRAPH_URL}/{FB_GRAPH_VERSION}/me/messages',
            params={
                'access_token': os.getenv('FB_ACCESS_TOKEN')
            },
            json={
                'recipient': {
                    'id': recipient
                },
                'message': {
                    'text': message
                }
            },
            timeout=10
        )
    finally:
        pass


def duckduckgo(query, count=10):
    c = 0
    try:
        response = requests.get('https://api.duckduckgo.com',
                                params={'q': query, 'format': 'json', 'no_html': 1, 'skip_disambig': 1},
                                timeout=10)
        data = response.json()
        if len(data['AbstractText']):
            yield data['AbstractText']
            c += 1
        for result in data['Results']:
            yield f"{result['Text']} - {result['FirstURL']}"
            c += 1
            if c == count:
                return
    finally:
        if not c:
            yield 'No results found'
        yield 'Search again'

Integrating a Flask application with Facebook

From the Webhook section, click Setup Webhooks, enter the Callback URL and the Verify Token we saved earlier. Select messages and messaging_postbacks and click Verify and Save.

Subscribe FreeSearch page to webhooks


Release for Public Use

From the developers dashboard, click Messenger > Settings and find App Review for Messenger section. Add pages_messaging to submission and submit your application for review.

App Reviews takes a while until you can find the chatbot on Messenger. Read Submitting Your Messenger Bot.


Search the Web for Free with FreeSearch

Using Facebook Messenger, find "FreeSearch" and start searching.


Credit where the credit is due

Searching with free data using Messenger is purely Miko Santos' idea. This blog was only written to show how to create a Messenger chatbot at virtually zero cost using Python, Flask, and DuckDuckGo.

Read more articles like this in the future by buying me a coffee!

Buy me a coffeeBuy me a coffee