How to attach a file to HubSpot contact through APIs, in Power Automate

With this article, the issues and solutions I am trying to address are:

  1. How to use HubSpot APIs
  2. How to upload a file to HubSpot
  3. How to make association between a Contact and the uploaded file
  4. How to achieve all of these using Power Automate

On a high level, below is the list of API tasks we have to do to achieve this. We have to make requests to three calls (one less if you have Customer ID already).

High level Power Automate flow

See below the high level flow I have created to demonstrate:

Prerequisites

  1. Basic knowledge in HubSpot. We would be interacting the CRM Contacts and Library
  2. Good knowledge in Power Automate
  3. A HubSpot account – Sandbox / Developer
  4. Create a Private App in HubSpot
  5. Get an Access Token
  6. Create a sample contact in HubSpot (for testing)
  7. Create a folder in the HubSpot Library (optional)

Detailed Flow

In this example, I am using a HTTP Request Trigger, which starts when we POST a file and a email-id (I used it to represent a customer in HubSpot contact form). I am doing some

Set the stage

For those struggling to get few items from the POST’ed content, find below details for your reference.

Using Postman to trigger a Power Automate HTTP flow

A. Get File content

triggerOutputs()['body']['$multipart'][0]['body']

B. Get filename

Honestly, I am not sure if there is a straight forward method available. This is my way of parsing filename from the Content-Disposition string:

// Input sample: "headers": {
//        "Content-Disposition": "form-data; name=\"email\"",
//        "Content-Length": "25"
//      }

// Power fx
trim(concat(split(split(triggerOutputs()['body']['$multipart'][0]['headers']['Content-Disposition'], 'filename="')[1], '"')[0]))

C. Get Email

triggerOutputs()['body']['$multipart'][1]['body']['$content']

HubSpot API Calls

Since the APIs for fetching Contact ID and Uploaded File ID are independent tasks, I am executing them in parallel.

A. Upload file, and get file id

I have used only minimum number parameters to avoid the confusion. I am uploading the file to a folder in the library.

Find the POST’ing JSON script for the Body. I see many people are struggling to make this correct.

{
  "$content-type": "multipart/form-data",
  "$multipart": [
    {
      "headers": {
        "Content-Disposition": "form-data; name=\"folderPath\""
      },
      "body": "/Sample Folder"
    },
    {
      "headers": {
        "Content-Disposition": "form-data; name=\"file\"; filename=\"@{variables('Filename')}\""
      },
      "body": @{variables('file')}
    },
    {
      "headers": {
        "Content-Disposition": "form-data; name=\"options\""
      },
      "body": {
        "access": "PRIVATE"
      }
    }
  ]
}

Upon successful upload, you will be receiving a JSON response with File ID.

B. Get the Customer ID of a contact using email as parameter.

This is a straight forward task. Just call the API using GET. Example: https://api.hubapi.com/crm/v3/objects/contacts/john@mathew.com?idProperty=email

C. Create Contact-File association

Once you have FileID and Contact ID, now you can POST a create-note API call to https://api.hubapi.com/crm/v3/objects/notes

Below is the JSON body you have to use:

{
    "properties": {
        "hs_timestamp": "2024-07-30T10:30:00.000Z",
        "hs_attachment_ids": "<File ID>"
    },
    "associations": [
        {
            "to": {
                "id": "<Customer ID>"
            },
            "types": [
                {
                    "associationCategory": "HUBSPOT_DEFINED",
                    "associationTypeId": 10
                }
            ]
        }
    ]
}

Note: associationTypeId is the magic number which tells the API to make Contact-File association. Please check the documentation for more association types.

Find the Power Automate action view:

Verify if the flow has worked

Go to HubSpot, select contact and you should be able to see the file attached.

Additionally, if you go to the Library -> Files -> Sample Folder, you can see the same file appearing there.

Article: Target Fixation Problem in IT

Views on how target fixation problem can be compared to impacting your career journey

The other day, I was reading about target fixation problem in vehicle driving and it occurred to me I have met many people in Information Technology field also with such a problem. Target fixation as per Wikipedia:

“an attentional phenomenon observed in humans in which an individual becomes so focused on an observed object that they inadvertently increase their risk of colliding with the object.”

In the fast-paced world of IT, it’s easy to get caught up in the rush of achieving specific career goals. One of the main problems with this is burnout. When an individual is too focused on climbing the corporate ladder or mastering a particular technology, they might end up working long hours without taking necessary breaks. This can lead to physical and mental exhaustion, ultimately affecting their productivity and health. Surprisingly, most of the time this is happening subconsciously so we don’t even think about it because it is a blind spot. One of my friend was so addicted to Microsoft SharePoint technologies and was really an expert in that. But he did not bother upskill even when Microsoft decided to strengthen its future by introducing Power Platform elements, such as Power Apps or Power Automate. For him those were alien tracks because he believed SharePoint is never outdated and never it will.

Moreover, target fixation can strain personal relationships. IT professionals who are constantly chasing their career goals might neglect their family and social life. This imbalance can lead to feelings of isolation and dissatisfaction, both personally and professionally. It’s essential to remember that a successful career should not come at the expense of one’s well-being and relationships.

Well, how do we overcome this problem?

Unfortunately, it doesn’t have a silver bullet fix. Recognizing and accepting the reality is the first step.

We have to adopt a balanced approach to cure this. Then set realistic and flexible career goals (SMART goals). Instead of obsessing over a single target, one should aim for a broader vision that includes professional growth, skill development, and personal happiness. Regularly reassessing and adjusting these goals can help in staying on the right track. Additionally, one should cultivate a diverse skill set. In the ever-evolving field of IT, being adaptable is key. By learning new technologies and exploring different roles, professionals can stay relevant and open to various opportunities. This not only reduces the pressure of achieving a single target but also enhances overall career prospects. Additionally, seeking support from mentors and peers can provide valuable insights and encouragement.

In conclusion, while setting career targets is essential, it’s equally important to avoid the pitfalls of target fixation. A balanced approach, continuous learning, and prioritizing well-being can help IT professionals achieve long-term success and fulfillment. Remember, a fulfilling career is one that grows harmoniously with personal happiness and health.

URL: https://www.linkedin.com/pulse/target-fixation-problem-career-praveen-nair–dwpac

Document summarizer using Open AI on LangChain

For the sake of a use case, the intention of this example is to summarize a resume. Google Colab was used for this experiment but you can use your own IDE/environment. Just make sure you have the necessary prerequicites set.

  1. Since I am using Google Colab, I will be uploading the sample input file to the “Files” store. You can choose to use your local disk storage if you are on a laptop/pc.
  2. While you can use any file format, I am using a pdf file as input so we have to convert the pdf to readable text. I will be using pdfx library to read and extract text data.
  3. A meaningful prompt and setting context will be done
  4. Access Open API API
  5. Receive response and show the summarized text.

Below are the instructions and code:

  1. Install Prerequisites

I am using pdfx library to read the pdf document. You can use any provider here.

pip install pdfx

We use OpenAI using LangChain so install the required dependencies

pip install --upgrade langchain langchain-openai tiktoken

2. Load Job Description (JD)

import pdfx
pdf = pdfx.PDFx('sample_data/Sample Resume.pdf')

resume_content = pdf.get_text();

3. Make the resume content compatible for LLM Chain

from langchain.docstore.document import Document
from langchain.text_splitter import CharacterTextSplitter
model_name = "gpt-3.5-turbo"
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
    model_name=model_name
)

# Caution: This code doesn't bother about large documents so chunking/tokenization is out of scope of this example
texts = text_splitter.split_text(resume_content)

docs = [Document(page_content=t) for t in texts]

4. Initialize OpenAI

from langchain_openai import ChatOpenAI
from google.colab import userdata


# Open AI API key is stored in the Secrets vault in Google Colab
OPENAI_API_KEY = userdata.get('openai_api_key')

llm = ChatOpenAI(
    temperature=0,
    openai_api_key=OPENAI_API_KEY,
    model_name=model_name)

5. Define summarization prompt

from langchain.prompts import PromptTemplate

# Use the prompt "List the skills mentioned in below resume:" to list the skills alone

prompt_template = """Summarize below resume:

{text}

"""

prompt = PromptTemplate(template = prompt_template, input_variables=["text"])

6. Summarization

from langchain.chains.combine_documents.stuff import StuffDocumentsChain
from langchain.chains import LLMChain

llm_chain = LLMChain(llm=llm, prompt=prompt)

#I am ignoring the chunking aspect
chain = StuffDocumentsChain(llm_chain=llm_chain, document_variable_name="text")
summary = chain.run(docs)

7. Print Summary

import textwrap
print(textwrap.fill(summary, width=100))

Example output: <name-removed> is a passionate researcher with a focus on cutting-edge technology such as Machine Learning, Computer Vision, and Deep Learning. He has experience as an Associate Data Scientist-Trainee at Lincode Labs and as an AI/ML Intern. His roles included data collection and cleaning, extending code modules, experimenting and deploying machine/deep learning models, and handling end-to-end processes. He has worked on various projects related to object detection, OCR detection, and classification in the manufacturing domain. <name-removed> has a Bachelor’s degree in Computer Science and skills in Python, machine learning platforms, frameworks, libraries, and tools. He has also worked on academic and personal projects related to border security systems and house price prediction.