Skip to content

Instantly share code, notes, and snippets.

@DaveOkpare
Last active February 9, 2024 21:06
Show Gist options
  • Save DaveOkpare/172340a50e65a5a895d29b4c5da954dc to your computer and use it in GitHub Desktop.
Save DaveOkpare/172340a50e65a5a895d29b4c5da954dc to your computer and use it in GitHub Desktop.
Automate email replies and drafts with Zapier and Langchain
# pip install -q langchain openai chromadb tiktoken
import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.llms import OpenAI
from langchain.chains import RetrievalQA, LLMChain, TransformChain, SimpleSequentialChain, SequentialChain
from langchain.document_loaders import TextLoader
from langchain.prompts import PromptTemplate
from langchain.tools.zapier.tool import ZapierNLARunAction
from langchain.utilities.zapier import ZapierNLAWrapper
# get from https://platform.openai.com/
os.environ["OPENAI_API_KEY"] = "<OPENAI_API_KEY>"
# get from https://nla.zapier.com/demo/provider/debug (under User Information, after logging in):
os.environ["ZAPIER_NLA_API_KEY"] = "<ZAPIER_NLA_API_KEY>"
loader = TextLoader("/content/resume.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_documents(texts, embeddings)
actions = ZapierNLAWrapper().list()
## step 1. gmail find email
GMAIL_SEARCH_INSTRUCTIONS = "Grab the latest email from David Ian"
def nla_gmail(inputs):
action = next((a for a in actions if a["description"].startswith("Gmail: Find Email")), None)
return {"email_data": ZapierNLARunAction(action_id=action["id"], zapier_description=action["description"], params_schema=action["params"]).run(inputs["instructions"])}
gmail_chain = TransformChain(input_variables=["instructions"], output_variables=["email_data"], transform=nla_gmail)
## step 2. generate retrieval question
question_template = """Converts this email into a one sentence question. Be concise. Use less than 30 words. Output question in plain text (not JSON).
Incoming email:
{email_data}
Question:"""
prompt_template = PromptTemplate(input_variables=["email_data"], template=question_template)
question_chain = LLMChain(llm=OpenAI(temperature=.7), prompt=prompt_template)
## step 3. draft email from context
context_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
Use the answer to write an email.
{context}
Question: {question}
Draft email:"""
PROMPT = PromptTemplate(
template=context_template, input_variables=["context", "question"]
)
chain_type_kwargs = {"prompt": PROMPT}
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever(), chain_type_kwargs=chain_type_kwargs)
retrieval = lambda inputs: {"retrieved_data": qa.run(inputs["question"])}
retrieval_chain = TransformChain(input_variables=["question"], output_variables=["retrieved_data"], transform=retrieval)
## step 4. save drafted email
def create_draft(inputs):
action = next((a for a in actions if a["description"].startswith("Gmail: Create Draft")), None)
instructions = f'Create a draft with this: {inputs["draft_reply"]}'
return {"gmail_data": ZapierNLARunAction(action_id=action["id"], zapier_description=action["description"], params_schema=action["params"]).run(instructions)}
draft_chain = TransformChain(input_variables=["draft_reply"], output_variables=["gmail_data"], transform=create_draft)
## finally, execute
overall_chain = SimpleSequentialChain(chains=[gmail_chain, question_chain, retrieval_chain, draft_chain], verbose=True)
overall_chain.run(GMAIL_SEARCH_INSTRUCTIONS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment