diff --git a/LinkedIn/LinkedIn_Rank_Direct_Conversations_by_Messages_Count.ipynb b/LinkedIn/LinkedIn_Rank_Direct_Conversations_by_Messages_Count.ipynb new file mode 100644 index 0000000000..15e6124f01 --- /dev/null +++ b/LinkedIn/LinkedIn_Rank_Direct_Conversations_by_Messages_Count.ipynb @@ -0,0 +1,330 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "corresponding-inspection", + "metadata": { + "execution": { + "iopub.execute_input": "2021-01-25T08:00:35.294800Z", + "iopub.status.busy": "2021-01-25T08:00:35.294557Z", + "iopub.status.idle": "2021-01-25T08:00:35.307281Z", + "shell.execute_reply": "2021-01-25T08:00:35.306468Z", + "shell.execute_reply.started": "2021-01-25T08:00:35.294775Z" + }, + "papermill": {}, + "tags": [] + }, + "source": [ + "\"LinkedIn.png\"" + ] + }, + { + "cell_type": "markdown", + "id": "smooth-empire", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "# LinkedIn - Rank Direct Conversations by Messages Count" + ] + }, + { + "cell_type": "markdown", + "id": "b9ae9ea3-f575-4ffc-b3c9-285569effca5", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "**Tags:** #linkedin #messages #analytics #dataframe #growth #sales" + ] + }, + { + "cell_type": "markdown", + "id": "1a958a79-fd53-4f43-8bdf-8ba026979057", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "**Author:** [Florent Ravenel](https://www.linkedin.com/in/florent-ravenel/)" + ] + }, + { + "cell_type": "markdown", + "id": "a7549883-358e-415b-860c-e28e04e490ab", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "**Last update:** 2024-06-26 (Created: 2024-06-26)" + ] + }, + { + "cell_type": "markdown", + "id": "naas-description", + "metadata": { + "papermill": {}, + "tags": [ + "description" + ] + }, + "source": [ + "**Description:** This notebook ranks direct conversations by message count. Don't forget to download your LinkedIn extract and use the messages.csv file as input." + ] + }, + { + "cell_type": "markdown", + "id": "70906835-ef47-4bf6-9e68-9841d72be87e", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "**References:**\n", + "- [LinkedIn Download data](https://www.linkedin.com/mypreferences/d/download-my-data)" + ] + }, + { + "cell_type": "markdown", + "id": "moderate-honey", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "## Input" + ] + }, + { + "cell_type": "markdown", + "id": "import_cell", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "### Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "changed-romance", + "metadata": { + "papermill": {}, + "tags": [] + }, + "outputs": [], + "source": [ + "import requests\n", + "import pandas as pd\n", + "from datetime import datetime" + ] + }, + { + "cell_type": "markdown", + "id": "continental-xerox", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "### Setup variables" + ] + }, + { + "cell_type": "markdown", + "id": "72e801c3-a434-446f-9575-3d3070edaf1f", + "metadata": {}, + "source": [ + "- `linkedin_url`: URL of LinkedIn profile\n", + "- `file_path`: Path to the messages.csv file\n", + "- `limit`: Limit of days to get the conversations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "diverse-maximum", + "metadata": { + "papermill": {}, + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "linkedin_url = \"https://www.linkedin.com/in/jeremyravenel\"\n", + "file_path = \"messages.csv\"\n", + "limit = 30" + ] + }, + { + "cell_type": "markdown", + "id": "inappropriate-theory", + "metadata": { + "execution": { + "iopub.execute_input": "2021-05-15T10:12:55.887028Z", + "iopub.status.busy": "2021-05-15T10:12:55.886761Z", + "iopub.status.idle": "2021-05-15T10:12:55.899441Z", + "shell.execute_reply": "2021-05-15T10:12:55.898476Z", + "shell.execute_reply.started": "2021-05-15T10:12:55.886964Z" + }, + "papermill": {}, + "tags": [] + }, + "source": [ + "## Model" + ] + }, + { + "cell_type": "markdown", + "id": "a49e3013-462d-4b1f-8bd6-38fe14b1dae5", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "### Get messages" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad6f4492-0c82-49a6-9c42-f9415a9ccf7f", + "metadata": { + "papermill": {}, + "tags": [] + }, + "outputs": [], + "source": [ + "# Read csv\n", + "df_conversations = pd.read_csv(file_path)\n", + "\n", + "# Include only \"INBOX\"\n", + "df_conversations = df_conversations[df_conversations[\"FOLDER\"] == \"INBOX\"].sort_values(by=\"DATE\", ascending=False).reset_index(drop=True)\n", + "print(\"Messages:\", len(df_conversations))\n", + "print(\"Conversations:\", len(df_conversations[\"CONVERSATION ID\"].unique()))\n", + "df_conversations.head(1)" + ] + }, + { + "cell_type": "markdown", + "id": "approved-greek", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "## Output" + ] + }, + { + "cell_type": "markdown", + "id": "0ed9fa57-ef5a-421d-be81-cf5848c80283", + "metadata": { + "papermill": {}, + "tags": [] + }, + "source": [ + "### Rank Direct Conversations by Messages Count" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7553d14d-5471-4b99-8df7-1aa63730daf9", + "metadata": { + "papermill": {}, + "tags": [] + }, + "outputs": [], + "source": [ + "def get_messages_counts(df_init, linkedin_url, limit):\n", + " # Init\n", + " public_id = linkedin_url.split(\"/in/\")[1].split(\"/\")[0]\n", + " df = df_init.copy()\n", + " \n", + " # Groupby conversation\n", + " df_output = df.groupby([\"CONVERSATION ID\"], as_index=False\n", + " ).agg({\"SENDER PROFILE URL\": \"nunique\", \"CONTENT\": \"count\"}\n", + " ).rename(columns={\"CONTENT\": 'COUNT'}\n", + " ).sort_values(by=\"COUNT\", ascending=False\n", + " ).reset_index(drop=True)\n", + " \n", + " # Keep only conversations (not group or one message without answer)\n", + " df_output = df_output[(df_output[\"SENDER PROFILE URL\"] == 2) & (df_output[\"COUNT\"] >= 2)].drop(\"SENDER PROFILE URL\", axis=1).reset_index(drop=True)\n", + " \n", + " # Get details\n", + " df_total = df[df[\"CONVERSATION ID\"].isin(df_output[\"CONVERSATION ID\"].unique())].groupby([\"CONVERSATION ID\", \"SENDER PROFILE URL\"], as_index=False).agg({\"CONTENT\": \"count\"})\n", + " df_me = df_total[df_total[\"SENDER PROFILE URL\"].str.contains(public_id)].reset_index(drop=True).rename(columns={\"CONTENT\": 'COUNT_ME'})\n", + " df_them = df_total[~df_total[\"SENDER PROFILE URL\"].str.contains(public_id)].reset_index(drop=True).rename(columns={\"CONTENT\": 'COUNT_THEM'})\n", + " df_output = pd.merge(df_output, df_me.drop(\"SENDER PROFILE URL\", axis=1), how=\"left\")\n", + " df_output = pd.merge(df_output, df_them, how=\"left\")\n", + " \n", + " # Get last messages\n", + " df_last = df[[\"CONVERSATION ID\", \"DATE\"]].drop_duplicates(\"CONVERSATION ID\")\n", + " df_last[\"DATE\"] = df_last[\"DATE\"].str[:-4]\n", + " df_last[\"DAYS_SINCE_LAST_MESSAGE\"] = (datetime.now() - pd.to_datetime(df_last[\"DATE\"])).dt.days\n", + " df_output = pd.merge(df_output, df_last, how=\"left\").rename(columns={\"DATE\": \"LAST_MESSAGE_DATE\"})\n", + " \n", + " # Filter on limit\n", + " df_output = df_output[df_output[\"DAYS_SINCE_LAST_MESSAGE\"] <= limit]\n", + " return df_output.reset_index(drop=True)\n", + "\n", + "df_messages_stat = get_messages_counts(df_conversations, linkedin_url, limit)\n", + "print(f\"Conversations over the last {limit} days:\", len(df_messages_stat))\n", + "df_messages_stat" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbb54439-55b9-49dd-bb79-62949f24d7ba", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.9.6" + }, + "naas": { + "notebook_id": "87b880ff840a772458fb40959783a6f1c58c8ade4b163685888a411f3096a25e", + "notebook_path": "LinkedIn/LinkedIn_Send_conversation_to_HubSpot_communication.ipynb" + }, + "papermill": { + "default_parameters": {}, + "environment_variables": {}, + "parameters": {}, + "version": "2.3.3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}