Automate Birthday Wishing On LinkedIn Using Python + Flask + ...

Pragnakalp

+91 97277 05677

[email protected]

Automate Birthday Wishing On LinkedIn Using Python + Flask + Selenium

Pragnakalp Techlabs > Automation > Automate Birthday Wishing On LinkedIn Using Python + Flask + Selenium Automate B'day wish on Linkedin October 19, 2021 No Comments

LinkedIn is a purely professional networking and employment-oriented website. It is a platform where the world’s employees and employers can meet and interact with each other. So when it comes to a special day like a birthday, then wishing without forgetting is a must to make stronger connections. Now you don’t need to worry about wishing all of them personally, you just need to use this script and run it to wish them together. Very fast and without much hustle. So let’s make this script! 

What is selenium?

Selenium is one of the free of the automated testing frameworks used to automate web browsers. We can use selenium with multiple languages like Java, Python, Ruby, C#, etc. Selenium is more than just a single tool; it’s a collection of tools, each of which caters to a certain organization’s Selenium QA testing requirements. Selenium Integrated Development Environment(IDE), Selenium Remote Control (RC), WebDriver, Selenium grid are tools of selenium. 

To automate the browser here, we will use the selenium WebDriver tool. Selenium WebDriver is a web framework that permits you to execute cross-browser tests. This tool is used for automating web-based application testing to verify that it performs expectedly.

Installation and getting started

When starting a new project in python, the ideal approach is to create a new environment and work in it. This is helpful because it separates other projects and their dependencies in distinct places, which allows for easy deployment if needed, and clear package-managing.

python -m venv env_name

After running this in cmd, the folder will be created with the name of your environment name. After creating the environment, activate it and now we will install our required dependencies for our project.

Install Selenium libraries for Python using pip. More info on installation can be found here.

pip install selenium

We have to install a web driver that Selenium will utilize to use the browser. We can use any browser, but here, we will use Chrome-Driver for Google Chrome/Chromium. You can download the web driver here.

For creating a web application, we have used Flask. For installing Flask in your virtual environment, use the command below.

pip install -U Flask

We have to install some other packages for this project. Create a requirements.txt file, add this into this file and run the below command. This will install all the packages which are needed in this project.

pip install -r requirements.txt

1. Creating .env file

To store the email ID and passwords, we will create a .env file and get the login credentials from the .env file.

Make sure that the format of the .env is exactly same as below. Here the first two env variables i.e. EMAIL & PASSWORD are used for LinkedIn Login, and the last two i.e. SENDER_EMAIL & SENDER_PASSWORD are used for Email authentication, which is used in exceptionMail.py file.

2. Creating a python file for sending mail.

If any exception occurs, or if a birthday is successfully wished, or if there is no birthday today, we will send a mail to the user. To do so, use the code below.

import smtplib, ssl from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import time import os # Defined sender email credentials in the .env file and accessing using os methods sender_email = os.getenv("SENDER_EMAIL") password = os.getenv("SENDER_PASSWORD") def sendMail(receiver_email, bodyMessage): message = MIMEMultipart("alternative") message["Subject"] = "RE: Your automatic birthday wisher" message["From"] = sender_email message["To"] = receiver_email # # Turn these into plain/html MIMEText objects part1 = MIMEText(bodyMessage, "plain") # Add HTML/plain-text parts to MIMEMultipart message # The email client will try to render the last part first message.attach(part1) # Create secure connection with server and send email context = ssl.create_default_context() try: with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server: server.login(sender_email, password) time.sleep(10) server.sendmail( sender_email, receiver_email, message.as_string() ) time.sleep(5) return "Mail sent" except Exception as e: print(e) return "Mail could not sent Exception is : {}".format(e)

3. Get the required terms using Inspect elements

By using the “inspect element”, we can detect that the email text box element contains the ID ‘username’. The password’s id is similar, with its id being ‘password’. We can utilize the ‘find_element_by_id’ function to get those elements in the HTML. After obtaining the text box elements, we can call the ‘send_keys(string)’ method on those boxes with a specified string.

4. Creating a Function for Login and wishing happy birthday.

Create a python file named linkedInBirthday.py and copy the below code in that file.

We will import the necessary Modules and Libraries for the python file.

import time import csv from bs4 import BeautifulSoup from datetime import date from exceptionMail import sendMail from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import pandas as pd from selenium.webdriver.common.action_chains import ActionChains import os

Then, we will use the username and password from the .env file.

# Defined sender email credentials in the .env file and accessing using os methods usr = os.getenv("EMAIL") pwd = os.getenv("PASSWORD")

First, we will go to the connection page and scrape all the connection’s details, profile links, and store it in the CSV file.

When the total connection is the same as in the CSV file, then we won’t scrape the user details, while running the script again.

We will iterate through all these pages and scrape all the connection details.

After scraping all user details, we will use those profile links and scrape the birthdate of each connection from the contact info section.

Follow the code given below.

#Declare the below variables header = ['name', 'Link', 'image', 'Bithday'] data = [] index = [] message = '' connList = {} birthdayList = {} last_page = 0 def runScript(): driver = webdriver.Chrome() driver.get('https://www.linkedin.com/login') print("Opened Linkedin") username_box = driver.find_element_by_id('username') username_box.send_keys(usr) print("Email Id entered") time.sleep(1) password_box = driver.find_element_by_id('password') password_box.send_keys(pwd) print("Password entered") login_box = driver.find_element_by_xpath( '//*[@id="organic-div"]/form/div[3]/button') login_box.click() time.sleep(10) print('logged in') time.sleep(3) driver.get( "https://www.linkedin.com/search/results/people/?network=%5B%22F%22%5D&origin=FACETED_SEARCH&sid=RUx") time.sleep(4) # Scrap the list of profiles def get_profile_of_a_page(): position = 0 birthdayslist = driver.find_elements_by_class_name( 'entity-result__item') for b in birthdayslist: profileLink = b.find_element_by_tag_name("a") name = profileLink.text linkk = profileLink.get_attribute("href") try: imageTagFinder = b.find_element_by_tag_name("img") image = imageTagFinder.get_attribute("src") except: image = 'https://www.pngarea.com/pngm/90/6980003_profile-icon-png-facebook-default-profile-picture-girl.png' connList[position] = {'link': linkk, 'name': name, 'image': image} position = position + 1 # Scrolling a full-page def scroll_till_end(): try: html = driver.find_element_by_tag_name('html') html.send_keys(Keys.END) except Exception as e: print(str(e)) # moving to next page def next_page(): try: next_button = driver.find_element_by_class_name( 'artdeco-pagination__button.artdeco-pagination__button--next.artdeco-button.artdeco-button--muted.artdeco-button--icon-right.artdeco-button--1.artdeco-button--tertiary.ember-view') driver.execute_script("arguments[0].click();", next_button) time.sleep(4) # break except Exception as e: print(e) # Add all connection details into the CSV file def addConnectionToCsv(): for user in connList: driver.get(connList[user]['link']) time.sleep(3) driver.find_element_by_class_name( 'ember-view.link-without-visited-state.cursor-pointer.text-heading-small.inline-block.break-words').click() time.sleep(2) try: birthdate = driver.find_element_by_class_name( 'pv-contact-info__contact-item.t-14.t-black.t-normal').text time.sleep(4) data.append([connList[user]['name'], connList[user] ['link'], connList[user]['image'], birthdate]) loopVar = loopVar + 1 # write multiple rows except Exception as e: print(e) with open('linkedinProfiles.csv', 'w', encoding='UTF8', newline='') as f: writer = csv.writer(f) # write the header writer.writerow(header) writer.writerows(data) # checks if today is somone's birthday or not def isbirthday(): today = date.today() # Textual month, day and year d2 = today.strftime("%B %#d %Y") currentDate = d2.split() currentDate.pop() dataOfCsv = pd.read_csv("linkedinProfiles.csv") # converting column data to list connectionBirthdates = dataOfCsv['Bithday'].tolist() for birthday in range(len(connectionBirthdates)): if connectionBirthdates[birthday].split() == currentDate: index.append(birthday) # Count data in CSV def dataInCSV(): try: dataInCsv = pd.read_csv("linkedinProfiles.csv") except Exception as e: print(e) return 0 listOfData = dataInCsv['Bithday'].tolist() print("totalCSVdata : ", len(listOfData)) return len(listOfData) # Fetch the total connection def totalConnection(): totConnection = driver.find_element_by_class_name( 'pb2.t-black--light.t-14').text conn = totConnection.split() conn.pop() print("totalConnectiondata : ", int(conn[0])) return int(conn[0]) # Get the list whose birthday is today def getBirthdayList(): listCount = 0 with open('linkedinProfiles.csv') as csv_file: csv_reader = csv.reader(csv_file) next(csv_reader) row = list(csv_reader) # fhandle = open('linkedinProfiles.csv') for ind in index: rowneeded = row[ind] birthdayList[listCount] = { 'name': rowneeded[0], 'link': rowneeded[1], 'image': rowneeded[2], 'birthday': rowneeded[3]} listCount = listCount + 1 def pageToScrape(): try: response = driver.page_source soup = BeautifulSoup(response, 'html.parser') all_pages = soup.find_all(class_="artdeco-pagination__indicator artdeco-pagination__indicator--number ember-view") global last_page if len(all_pages)>0: print("total pages:",len(all_pages)) last_page = all_pages[-1].text print("last_page",all_pages[-1].text) else: print("No data") last_page = 1 except: print("Can't find the element") # Check the count of connections in CSV and the actual connection count if dataInCSV() == totalConnection(): print("Finding the bithday of connections") isbirthday() getBirthdayList() else: print("Scraping the connections details\n") pageToScrape() for i in range(int(last_page)): scroll_till_end() get_profile_of_a_page() # profile scrapping function! scroll_till_end() next_page() time.sleep(4) addConnectionToCsv() print("Finding the bithday of connections") isbirthday() getBirthdayList() print(index) # Sends the message def sendMessage(): global message global index global connList if index != []: message = "Birthday wished" connListFromCSV = pd.read_csv("linkedinProfiles.csv") BirthdayConnLinks = connListFromCSV['Link'].tolist() for indexNumber in index: link = BirthdayConnLinks[indexNumber] # Logic to send Message driver.get(link) time.sleep(4) msg = driver.find_element_by_link_text('Message').click() time.sleep(3) inbox = driver.find_element_by_class_name( 'msg-form__contenteditable.t-14.t-black--light.t-normal.flex-grow-1.full-height.notranslate') inbox.send_keys('Happy Birthday') time.sleep(3) send = driver.find_element_by_class_name( 'msg-form__send-button.artdeco-button.artdeco-button--1') ActionChains(driver).move_to_element( send).click(send).perform() time.sleep(3) try: close = driver.find_elements_by_class_name( 'msg-overlay-bubble-header__control.artdeco-button.artdeco-button--circle.artdeco-button--muted.artdeco-button--1.artdeco-button--tertiary.ember-view') for closebut in close: closebut.click() except: print("No close button found") exp = "There is some problem sending the message, try again or contact the developer." sendMail(receiver_email=usr, bodyMessage=exp) time.sleep(3) print('Message send') else: message = "No more birthday for today" sendMessage() return message, birthdayList driver.close()

You will find the whole script here.

Now we will use this runScript() function in our flask project.

What is Flask?

Flask is a python web framework, for developing web applications.

Here, we will use Flask for running our script and Displaying user information or any other error that occurs while running the script.

The File Structure

We will create a flask app named flask_app.py. In this file, we will import the required modules and some functions of linkedInBirthday.py, add the following code in flask_app.py

from flask import Flask, render_template, redirect, session, url_for import time import os from linkedInBirthday import runScript app = Flask(__name__) app.secret_key = os.urandom(24) birthdayData = {} index = [] @app.route('/') def hello_world(): return render_template('home.html') @app.route('/running-script') def running_script(): data = runScript() print(data[0]) session['messages'] = data[0] global birthdayData global index birthdayData = data[1] return redirect(url_for('.success', messages = data[0])) @app.route('/success') def success(): # messeges = request.args['messages'] global birthdayData messages = session['messages'] return render_template('/success.html', messages = messages, birthday = birthdayData) if __name__ == '__main__': app.run(debug=True)

Now we will create two HTML files in the template folder.

The first home.html, add the following code in it. It’s the start-up page when we run the flask app.

Facebook-script

Executing the Script..............

Execute the Script

The second is success.html. This HTML template will display the status of the runScript() and print User information if there is a birthday today from your connections. Add the following code to it.

Success

Script Executed, {{ messages }}

{% for b in birthday %} {{ birthday[b]['name'] }} {{ birthday[b]['birthday'] }} {% endfor %}

For a CSS file create a folder like this. –> static/styles. In styles, folder create CSS file name home.css and add following code in it.

body { background: white; font-family: "Poppins", sans-serif; } .btnn { text-decoration: none; outline: none; padding: 10px 20px; background: rgb(190, 255, 194); color: rgb(2, 2, 2); border: none; border-radius: 3px; cursor: pointer; transition: all 0.5s; margin: 10px auto; width: max-content; text-align: center; } .btnn:hover { background-color: rgb(85, 255, 96); } .signupStyle { display: flex; justify-content: center; align-content: center; margin-top: 300px; flex-direction: column; } /* For layout purpose */ .BasicLayout { width: 1100px; height: auto; max-width: 75%; padding: 30px 50px; float: left; margin: 0 auto; margin-bottom: 2em; display: flex; flex-direction: column; } .outerDiv { display: flex; } .profileCards { margin-top: 25px; display: flex; width: 310px; border-radius: 5px; margin-right: 5px; justify-content: space-around; padding: 15px; align-items: center; background-color: rgb(223, 255, 225); } .profileImage { width: 110px; height: 110px; border-radius: 50%; } .profileName { font-size: 1.6em; font-weight: 500; color: rgb(55, 255, 68); } .flexDir{ display: flex; gap: 10px; } .ProcessingDiv{ display: flex; height: 100%; }

To run the flask app

python flask_app.py

After running this script, copy the URL from the command prompt and open it into the browser. Click on the “Execute the script” button. The script will wish if there are any birthdays and will display name and birthday of user whom the birthday is wished.

That’s it!

You can also put this script to run daily using cron job and you will be wishing Birthday wishes to your LinkedIn friends daily!

Write a comment Cancel reply

Your email address will not be published. Required fields are marked *

Post Comment

Search

Our Services

  • Gen AI Development
  • NLP service
  • Python Development
  • Chatbot Development
  • Quality Assurance
  • DevOps/MLOps

Case Studies

  • A Comparative Analysis of Meta-LLaMA and Mistral Models in Multilingual RAG System
  • Innovative Legal Insights: Case Study on Assessing Generative AI Models in Dialogflow CX Knowledge Base for Crafting an AI Chatbot.
  • NLP Based Resume Parser Using BERT in Python
  • BERT based QnA, Information Extractor and Closed-domain Chatbot
  • Closed-Domain Chatbot using BERT in Python
  • Question Answering System in Python using BERT NLP
  • “Railway Buddy” Chatbot Case Study (Dialogflow, Python)

Recent Posts

  • Custom AI Voice Agent with LiveKit and Voice AI
  • Get Your First Healthcare AI Agent in Just 5 Days!!
  • n8n Workflow to Automate Blog Publishing from Google Docs to WordPress
  • Accountant AI: Automate Invoice Parsing from Email to Google Sheets using n8n Workflow
  • n8n Workflow Automation to Parse Resumes from Gmail and Store in Google Sheets

Categories

  • Agentic AI
  • AI Agent
  • Amazon Alexa
  • Artificial Intelligence
  • Automation
  • AWS
  • AWS ECR
  • AWS lambda
  • Azure
  • Bulk Data Upload
  • chatbot
  • Chatbots Development
  • Chatfuel
  • ChatGPT
  • Company
  • Computer Vision
  • ControlNet
  • Data Extraction
  • Data migration
  • Data Science
  • Dialogflow
  • Dialogflow CX
  • Dialogflow Tutorial
  • Discord Bot
  • Django
  • Docker
  • Error Fix
  • Facebook Messenger
  • Gemini
  • GPT Builder
  • GPT-3
  • GPT-4o
  • Gunicorn
  • How To
  • Image Processing
  • Machine Learning
  • Microsoft Fabric
  • n8n workflow
  • Natural Language Processing
  • Nginx
  • NLP
  • OpenAI
  • PaliGemma
  • Playwright
  • Python
  • RAG Bot
  • Scraping
  • Scrapping
  • Selenium
  • Server Setup
  • Slack bot
  • Stable Diffusion
  • Telegram Bot
  • Voice Bot
  • Web Testing
  • WhatsApp Bot

Tags

<h3> ai AI Agent Data Lakehouse Data Science healthcare Machine Learning Microsoft Fabric music nlp Notebook
Pragnakalp Techlabs: Your trusted partner in Python, AI, NLP, Generative AI, ML, and Automation. Our skilled experts have successfully delivered robust solutions to satisfied clients, driving innovation and success.
Facebook X-twitter Linkedin Instagram Youtube Github Medium

Hire Dedicated Developers

  • Hire GenAI Developer
  • Hire Prompt Engineer
  • Hire NLP Engineer
  • Hire Chatbot Developer
  • Hire Automation Engineer
  • Hire Django Developer
  • Hire QA

Services

  • Chatbot Development
  • Natural Language Processing
  • Generative AI
  • Python Programming
  • Quality Assurance
  • DevOps/ MLOps
Contact Us
+91 97277 05677 [email protected] D-916, Ganesh Glory 11, Jagatpur Road, Gota, Ahmedabad – 382481 314, Queen’s Arcade, Near Chikhli Char rasta, Chikhli, Gujarat - 396521 TF80, The Wilson Point, Italva, Navsari, Gujarat - 396445 © 2024 Pragnakalp Techlabs - Generative AI, NLP, Chatbot & Python Development Company

Want to talk to an Expert Developer?

Our experts in Generative AI, Python Programming, and Chatbot Development can help you build innovative solutions and scale your business faster.

Share Your Questions Schedule a FREE Consultation

Thanks!

Tag » How To Send Birthday Wishes Email With Python