{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "cc3d4ef7", "metadata": {}, "outputs": [], "source": [ "from google import genai\n", "from google.genai import types\n", "from datetime import datetime\n", "from pydantic import BaseModel\n", "import os\n", "\n", "class JobSuggestion(BaseModel):\n", " company_name: str\n", " company_description: str\n", " job_title: str\n", " application_text: str\n", "\n", "# Load CV from file\n", "with open(\"cv_sebastian_egli.txt\", \"r\", encoding=\"utf-8\") as f:\n", " cv = f.read()\n", "\n", "# Load already suggested companies from file (to avoid duplicates)\n", "with open(\"already_suggested_companies.txt\", \"r\", encoding=\"utf-8\") as f:\n", " already_suggested_companies = f.read()\n", "\n", "# Define boolean for even-numbered days (I want to switch un/solicited every day)\n", "today = datetime.today()\n", "unsolicited_application = today.day % 2 == 0\n", "\n", "if unsolicited_application:\n", " query = [\"\"\"Analysiere meinen Lebenslauf (cv) und die Liste bereits vorgeschlagener Unternehmen (already_suggested_companies). \n", "Schlage mir genau ein Unternehmen in der Nähe von Marburg vor, das noch nicht in already_suggested_companies enthalten ist \n", "und für eine Initiativbewerbung besonders gut zu meinem Profil passt. \n", "\n", "Erkläre in maximal 150 Wörtern prägnant, warum dieses Unternehmen eine besonders gute Wahl für mich wäre. \n", "Formuliere die Antwort als kurze, professionelle Email mit dem Titel: 'Neuer Jobvorschlag'. \n", "Begründe die Eignung anhand meiner Qualifikationen und Interessen. \n", "Füge außerdem einen einzelnen Satz hinzu, der direkt in einem Bewerbungsschreiben genutzt werden könnte, \n", "um die Übereinstimmung zwischen mir und dem Unternehmen hervorzuheben. \n", "\n", "Liefere nur die Email, keine zusätzliche Erklärung.\"\"\",already_suggested_companies,cv]\n", "else:\n", " query = [\"\"\"Analysiere meinen Lebenslauf (cv) und die Liste bereits vorgeschlagener Unternehmen (already_suggested_companies). \n", "Schlage mir genau eine aktuell offene Stellenausschreibung in der Nähe von Marburg vor für ein Unternehmen, das noch nicht in already_suggested_companies enthalten ist \n", "und die besonders gut zu meinem Profil passt. \n", "\n", "Erkläre in maximal 150 Wörtern prägnant, warum diese Stelle eine besonders gute Wahl für mich wäre. \n", "Formuliere die Antwort als kurze, professionelle Email mit dem Titel: 'Neuer Jobvorschlag'. \n", "Begründe die Eignung anhand meiner Qualifikationen und Interessen. \n", "Füge außerdem einen einzelnen Satz hinzu, der direkt in einem Bewerbungsschreiben genutzt werden könnte, \n", "um die Übereinstimmung zwischen mir und der ausgeschriebenen Stelle hervorzuheben. \n", "\n", "Liefere nur die Email, keine zusätzliche Erklärung.\"\"\",already_suggested_companies,cv]" ] }, { "cell_type": "code", "execution_count": 2, "id": "7c68f66d", "metadata": {}, "outputs": [], "source": [ "api_key = os.environ.get(\"GEMINI_API_KEY\")\n", "\n", "client = genai.Client(api_key=api_key)\n", "\n", "# Step 1: grounded search (necessary for live web search)\n", "resp_grounded = client.models.generate_content(\n", " model=\"gemini-2.5-flash\",\n", " contents=query,\n", " config=types.GenerateContentConfig(\n", " tools=[types.Tool(google_search=types.GoogleSearch())]\n", " ),\n", ")\n", "\n", "grounded_answer = resp_grounded.text # freeform answer" ] }, { "cell_type": "code", "execution_count": 3, "id": "fe54c9a2", "metadata": {}, "outputs": [], "source": [ "# Step 2: convert to JSON\n", "resp_json = client.models.generate_content(\n", " model=\"gemini-2.5-flash\",\n", " contents=f\"Turn this answer into JSON: {grounded_answer}\",\n", " config=types.GenerateContentConfig(\n", " response_mime_type=\"application/json\",\n", " response_schema=JobSuggestion,\n", " ),\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "476ae4e4", "metadata": {}, "outputs": [], "source": [ "# Append the response to already_suggested_companies.txt\n", "with open(\"already_suggested_companies.txt\", \"a\", encoding=\"utf-8\") as f:\n", " f.write(\"\\n\" + resp_json.parsed.company_name)" ] }, { "cell_type": "code", "execution_count": 5, "id": "c3d72c4f", "metadata": {}, "outputs": [], "source": [ "import smtplib\n", "from email.mime.text import MIMEText\n", "\n", "gmail_key = os.environ.get(\"GMAIL_PW\")\n", "\n", "# Account details\n", "sender = \"seb.egli@gmail.com\"\n", "recipient = \"seb.egli@gmail.com\"\n", "password = gmail_key\n", "\n", "# Create email\n", "msg = MIMEText(grounded_answer)\n", "msg[\"From\"] = sender\n", "msg[\"To\"] = recipient\n", "msg[\"Subject\"] = \"Neuer Jobvorschlag\"\n", "\n", "# Send email using Gmail's SMTP\n", "with smtplib.SMTP_SSL(\"smtp.gmail.com\", 465) as server:\n", " server.login(sender, password)\n", " server.sendmail(sender, recipient, msg.as_string())" ] } ], "metadata": { "kernelspec": { "display_name": "odc-landsat", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.0" } }, "nbformat": 4, "nbformat_minor": 5 }