DEV Community

James White
James White

Posted on

Simple App on Google Cloud Functions from scratch

Requirements

  • Software required: python 3.7.x, pip3, git, ssh-keygen
  • Time: 30 mins
  • Accounts:
    • Telegram for messaging
    • Google Cloud free tier, credit card required :(
  • Cost: 0.00

Why?

I wanted to learn how to use Google Cloud Functions by building a simple but useful app.

Steps

1. Create a Google Cloud a/c

So unfortunately, like with AWS, you need a credit card to signup. At the moment Google are offering $300 credit for first year, but we don't want to spend any of that credit.

2. Create New Project

Create a new project and give it a name, this project will contain all the cloud components used.

new project
new project

3. Cloud Function

This is the serverless function that will execute periodically. Cloud Functions support various languages, we will be using python 3.7 which is currently in beta but isn't everything in Google? ;)


Use the settings in screenshot below...


Use the settings in screenshot below, some you may wish to change:

  • Repository Name: use the name of the repository you created
  • Function to execute: the name of the python function to execute
  • Region: pick whichever region is most appropriate for your use case
  • Environment Variables: Add as many env variables as you wish, choose appropriate variables to store here. Note: in this example 2 secrets are stored as environment variables to remove them from source code, much better practice is to use Googles KMS to encrypt secrets and store them in Cloud storage, but this is outside the scope of this post.

Choose Create and the function will be created, this can take a few mins as the repository is resolved and verified to match the configuration, any problems will be displayed and must be resolved before function is active.

4. Source Repo

Navigate to Source Repositories under Tools section of left menu.
Choose Add repository
Chose Create new repository and give it an appropriate name.

Now you need to clone the repository locally so you can modify it and push changes back.
If you have an ssh key already skip the next step, otherwise...
Linux: type ssh-keygen and fill in required details

Your new key pair will be in the directory you specified, the .pub file will be uploaded to Google.

Time to register the key, choose the Register the SSH key option and make sure to use your public key, usually found here: ~/.ssh/id_rsa.pub

Now clone the repo using the command shown: git clone ....

5. Simple source code

The code is pretty simple, it does the following on execution:

  1. Download rss and parse
  2. Send new bargains via telegram
import os, json, base64
from calendar import timegm
from datetime import datetime
import requests
import feedparser 

MINS_DIFF = 5
SLICKDEALS = 'https://slickdeals.net/newsearch.php?mode=frontpage&searcharea=deals&searchin=first&rss=1'

def go(event, context):
    num_deals_found = check_slick_deals()
    print(f'Found {num_deals_found} deals')

def check_slick_deals():
    items_found = 0
    try:
        NewsFeed = feedparser.parse(SLICKDEALS)
        for entry in NewsFeed.entries:
            publish_date = entry['published_parsed']
            # use appropriate timezone here 
            dt = datetime.fromtimestamp(timegm(publish_date)) 
            nownow = datetime.utcnow()
            mins_diff = abs((nownow - dt).total_seconds()) / 60
            if mins_diff < MINS_DIFF:
                items_found = items_found + 1
                send_message(f"{entry['title']} {entry['link']}")
    except Exception as e:
        print(f'Error parsing newsfeed: {e}')
    return items_found

def send_message(message):
    api_hash = os.environ.get('API_HASH', None)
    chat_id = os.environ.get('CHAT_ID', None)
    if api_hash is None or chat_id is None:
        print('Please set API_HASH and CHAT_ID env variables')
        return        
    api_url = f'https://api.telegram.org/bot{api_hash}'
    payload = {}
    payload['chat_id'] = chat_id
    payload['text'] = message
    r = requests.post(f'{api_url}/sendMessage', data=payload)

if __name__== "__main__":
    go(None, None)

Make sure you call the file main.py and add a corresponding requirements.txt, push them both to git repo with the following commands:

git add main.py requirements.txt
git commit -m 'adding initial files'
git push

Now the code is sitting in the repo, ready to be executed by the Cloud Function.

6. Cloud Schedule

We now have:

  • Source code sitting in cloud repo, ready to be cloned by function
  • Cloud Function to execute source when triggered
  • Pubsub topic that will trigger source when message received

We just need something to add a message and kick off the function, Cloud Scheduler is perfect for that.

First decide on what schedule you want the function to execute. I chose every 5 minutes, the cron for this is */5 * * * * https://crontab.guru/ is a great website that can help create an accurate cron configuration.

When you are finished, it should look something like this:

7. Done!

Congratulations, your new app is living in the cloud, laying dormant until a schedule wakens it from it's slumber.

Once you have created your first serverless app, it's exciting to think what else is possible, please let me know what you create and I will do the same :)

Top comments (0)