Daily News Report with Bing News Search and Twilio SMS

April Speight - Nov 16 '20 - - Dev Community

This article is part of #PythonFunBites.

When I decided to shift my career focus to Extended Reality (XR), I had only brushed the surface of what was happening in the industry. I knew that if I wanted to get more comfortable speaking about hot-topics and industry trends, I had to stay up to date on the latest news. I personally don't keep up with tech news sites so I had to find a way that would keep me informed without the need to engage on yet another social media platform. That's when I had the idea to bring the news to me! Rather than seek new articles, I figured I could automate the process instead.

Using Python, Azure Functions, Bing News Search, and Twilio SMS, I created a daily SMS that sends me the latest articles related to XR. Check out how I made it below!

Requirements:

Tutorial

1. Create a Project Folder and Open in Visual Studio Code

Create a folder to store all the project files and save to your preferred location. In Visual Studio Code, open the folder by navigating to File > Open (Ctrl+o/Cmd+o).

2. Sign in to Azure in Visual Studio Code

In the left Activity Bar of Visual Studio Code, click on the Azure icon to open the Azure view. Select Sign In to Azure. You will be taken to the browser to sign-in. Enter the credentials to your Azure account. Back in Visual Studio Code, you can confirm whether you're signed in if your username appears in the Status Bar.

3. Create a Bing Resource

In the Azure Portal, navigate to Create a resource. In the search bar, search for Bing Search v7. Select the resource and click Create. On the Create page, enter/select the following:

Name: Name of the resource
Subscription: Your Azure subscription
Pricing Tier: Free (if available, otherwise select your preferred pricing)
Resource Group: Either create a new resource group or select an existing one.
Region: Location where the function is used

A screenshot of the Create page for the Bing Search v 7 resource.

4. Install Azure Functions Core Tools

Azure Functions Core Tools enables you to create and test Azure Functions from the command line or terminal prompt. Review the docs to determine the proper installation process according to your OS.

To verify whether Azure Functions Core Tools is instead, run the command func in the Visual Studio Code integrated terminal (Ctrl+~). If Azure Functions Core Tools is successfully installed, the Azure Functions logo appears in the terminal (you may need to scroll up to see).

A screenshot of the terminal in Visual Studio Code. The Azure Functions logo appears after entering the command func.

5. Create a New Project

In the Azure view, click the Create New Project icon. Visual Studio Code takes you through a workflow to create a new project. Enter/select the following for each step:

Folder: Folder created earlier in the tutorial
Language: Python
Python alias or Full Path: Your Python interpreter
Template: Timer Trigger
Function Name: Name the function whatever you'd like
CRON expression: 0*/1**** (this runs the functions every minute)

After Visual Studio Code creates the function, a few files are added to the project folder. The init.py file opens in the editor.

Make sure to activate the virtual environment if Visual Studio Code does not do so for you.

Windows: .venv\Scripts\activate
Mac/Linux: source .venv/bin/activate

6. Install and Import Required Modules

Install the following modules:

Python-dotenv (access environment variables): pip install python-dotenv
Requests (for GET requests to Bing News Search API): pip install requests
Twilio Python Helper library: pip install twilio

At the top of the init.py file, enter the following import statements:

import datetime
import logging
import azure.functions as func
import json
import requests
from twilio.rest import Client
from dotenv import load_dotenv
load_dotenv()
import os
Enter fullscreen mode Exit fullscreen mode

7. Create and Access Environment Variables

In the Explorer view (Shift+Ctrl+e/Shift+Cmd+e), create a new .env file at the root of the folder. In the .env file, enter the following:

TWILIO_ACCOUNT_SID=<Replace with Twilio Account SID>
TWILIO_AUTH_TOKEN=<Replace with Twilio Auth Token>
MY_TWILIO_NUMBER='<Replace with your Twilio phone number>'
RECEIVER_NUMBER='<Replace with your personal phone number>'
BING_SUBSCRIPTION_KEY=<Replace with your Bing Search v7 resource subscription key>
BING_ENDPOINT=https://api.bing.microsoft.com/v7.0/news/search
Enter fullscreen mode Exit fullscreen mode

Replace the values with your credentials. All Twilio credentials and phone numbers are accessible in the Twilio Console. The Azure credentials are available in the Azure Portal within the Bing Resource.

Note: Be sure to include the country code before the phone number. Ex: +13235555555

In the init.py file, enter the following below the import statements:

account_sid = os.getenv("TWILIO_ACCOUNT_SID")
auth_token = os.getenv("TWILIO_AUTH_TOKEN")
my_twilio_number = os.getenv("MY_TWILIO_NUMBER")
receiver_number = os.getenv("RECEIVER_NUMBER")
subscription_key = os.getenv("BING_SUBSCRIPTION_KEY")
my_endpoint = os.getenv("BING_ENDPOINT")
Enter fullscreen mode Exit fullscreen mode

8. Create Bing New Search GET Request

In the init.py file within the main function, enter the following:

'''
    This sample makes a call to the Bing News Search API with a text query and returns relevant news webpages.
    Documentation: https: // docs.microsoft.com/en-us/azure/cognitive-services/bing-web-search/
    '''
    query = "<Replace a search term. Ex: Microsoft>"

    # Construct a request
    mkt = 'en-US' # change if necessary
    params = {'q': query, 'mkt': mkt}
    headers = {'Ocp-Apim-Subscription-Key': subscription_key}

    # Call the API

    response = requests.get(my_endpoint, headers=headers, params=params)
    response_json = response.json()

    title = response_json['value'][1]['name']
    description = response_json['value'][1]['description']
    article_url = response_json['value'][1]['url']
Enter fullscreen mode Exit fullscreen mode

9. Create Twilio Message

Below the block of code for the Bing News Search GET request, enter the following:

# Twilio account credentials
    twilio_client = Client(account_sid, auth_token)


    message = twilio_client.messages \
        .create(
            body=f"Title: {title} \n\n {description} \n\n {article_url}",
            from_=my_twilio_number,
            to=receiver_number
        )

    print(message.sid)
Enter fullscreen mode Exit fullscreen mode

Note: Feel free to update the message body!

10. Add Requirements to requirements.txt

Update the requirements.txt file with the following:

azure-functions
requests
twilio
python-dotenv
Enter fullscreen mode Exit fullscreen mode

11. Run in the Debugger

You can now test the function! Before you proceed, make sure that the init.py file reflects the following:

import datetime
import logging
import azure.functions as func
import json
import requests
from twilio.rest import Client
from dotenv import load_dotenv
load_dotenv()
import os

account_sid = os.getenv("TWILIO_ACCOUNT_SID")
auth_token = os.getenv("TWILIO_AUTH_TOKEN")
my_twilio_number = os.getenv("MY_TWILIO_NUMBER")
receiver_number = os.getenv("RECEIVER_NUMBER")
subscription_key = os.getenv("BING_SUBSCRIPTION_KEY")
my_endpoint = os.getenv("BING_ENDPOINT")

def main(mytimer: func.TimerRequest) -> None:

'''
    This sample makes a call to the Bing News Search API with a text query and returns relevant news webpages.
    Documentation: https: // docs.microsoft.com/en-us/azure/cognitive-services/bing-web-search/
    '''
    query = "<Replace with a search term. Ex: Virtual Reality>"

    # Construct a request
    mkt = 'en-US' # change if necessary
    params = {'q': query, 'mkt': mkt}
    headers = {'Ocp-Apim-Subscription-Key': subscription_key}

    # Call the API

    response = requests.get(my_endpoint, headers=headers, params=params)
    response_json = response.json()

    title = response_json['value'][1]['name']
    description = response_json['value'][1]['description']
    article_url = response_json['value'][1]['url']
    # Twilio account credentials
    twilio_client = Client(account_sid, auth_token)


    message = twilio_client.messages \
        .create(
            body=f"Title: {title} \n\n {description} \n\n {article_url}",
            from_=my_twilio_number,
            to=receiver_number
        )

    print(message.sid)
Enter fullscreen mode Exit fullscreen mode

Start the Debugger by navigating to Run > Start Debugging (F5). The first time you run the Debugger, Visual Studio Code prompts you to select an Azure Storage Account. Follow the prompts to create a storage account (or use one that you may already have created).

After the storage account is created/selected for the function, Visual Studio Code starts the debugger. If you receive an error, stop the debugger and enter func host into the terminal.

You should receive a SMS generated every minute to your phone if all is successful. If you do not receive a message, review all of the steps to check what may have been missed.

A screenshot of the S M S generated by the Azure function. The S M S provides a news article about Microsoft.

12. Update the CRON Expression

You're just about ready to deploy the function to Azure! But just before you do that, update the CRON expression in the function.json file. By default, the Azure Function uses the UTC timezone. Therefore, you need to set a time in that timezone that equates to 9AM in your specific timezone. Since I'm in California, I follow Pacific Daylight Time. Therefore, my CRON expression for everyday at 9AM would be: 0 * 17 * * *. For those on the East Coast, the CRON expression would be: 0 * 14 * * *.

If you fall outside either of those timezones, you can use a time zone converter to figure out the equivalent to 9AM for UTC in your time zone.

13. Deploy to Azure

You're now ready to deploy the function to Azure! In the Azure view, select the deploy icon (it's an up arrow). Visual Studio Code provides a workflow to complete deployment. Enter/select the following for each step of the workflow:

Select Function App: Create new Function App in Azure
Globally Unique Name: Provide a unique name for the function
Version of Python: Select the version that was selected earlier when creating the function
Location for New Resources: Select the location selected for the storage account

Azure then begins to deploy the function. After the function is deployed, you can anticipate receiving a SMS at your desired time interval. If you need to modify anything related to the function, you can do so within the project files in Visual Studio Code.

Need to stop the function? You can do so in the Azure portal. Navigate to Resource Groups and select the resource group used for the function. Select Delete resource group and follow the instructions to delete the resource.

And that's it! If you're feeling a little shaky on Azure Functions or would like to learn more about the service, check out the Microsoft Learn module.

Watch for content on all things Python at Microsoft between the 16th and 20th of November. Stay tuned here at dev.to for all kinds of content ranging from IoT, to Machine Learning and much more! 🐍

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player