The majority of Search steps in Zapier work on a 1-to-1 basis.
For example - if we want to Find a Person in Pipedrive by email - we have to put in one (and only one) email address.
But what if we need to look up 2 email addresses in Pipedrive?
One option is just to add a second Find Person action - and look up one email address per action.
That’s a reasonable solution if we always know exactly how many email addresses we’ll need to search.
However - if this number will vary - this can get complex.
Looping + Storage
Zapier has 2 built-in tools that can help us do multiple searches for a variable number of items.
Looping by Zapier - will enable us to Loop through a series of data.
And Storage by Zapier will enable us to temporarily store the results.
Both of these options can also get complex in a hurry. :)
Below - I’ll walk through a slightly advanced example of how we can use Looping and Storage to do multiple lookups and use that data in a subsequent step of the Zap.
The Trigger Data
For our example - we’re going to build on my Pipedrive Find Person action above.
Here’s the context.
I have a button on my website that my users can click to get a phone call from my support team.
When the user clicks this button - their email address is recorded - but their phone number is not.
Additionally - some website users might not have an email address - and we display an error message to them - but the click still gets recorded.
Finally - these requests are stored on my site and sent to Zapier in a batch every 15 minutes by webhook.
This means my webhook data might look like this below - with an unknown number of email addresses (and even some blanks).
The Actions
What I want to do is take the email addresses - and find the matching Person record in Pipedrive so I can pull in the Names and Phone Numbers for each email address.
And then I want to post a message for my Team in Slack so each user can get a call back.
Step 1 - Looping by Zapier
The first thing we are going to add immediately after the trigger is our Looping Step.
We have 3 options when configuring this trigger.
Since our data is a comma separated string - we’re going to choose Create Loop from Text.
And we’ll give a name to our data (Email Addresses) as well as map in the data we want to loop (the emails from the trigger).
The default delimiter is a comma and we’ll leave that as is since our list is comma separated.
Then we’ll run the test.
There are a couple of things to note from that test above.
The first 2 fields we see (loop_iteration and Email Addresses) are the first values that will be looped - the first run.
We’ll use these to configure the next steps of our Zap.
The data under preview_loop_values shows all the iterations for our loop that would be executed when our Zap Runs live.
In this case the total is 5. Our 3 email addresses and the 2 blanks
Step 2 - Paths A and B
Next - we’re going to add 2 Paths to the Zap Immediately after the Looping action.
Path A is where we are going to Lookup the Pipedrive Data.
Path B is going to post our Slack Message once we have looked up all the data from Pipedrive.
If we didn’t have the blank values in our trigger - we wouldn’t necessarily need these Paths.
But because we do have the blanks - the Paths will help us isolate the last record to send our Slack Message.
Path A Criteria
I really don’t want the Pipedrive Search to run for any of the blank email addresses - since I’ve already displayed a message for those users on my site.
And they won’t find a match in Pipedrive anyway.
So we’re going to configure Path A to only continue when the Email Addresses from our Looping step exists.
From this point forward - we’ll use the actual Field Name (Email Addresses for example) when configuring our actions - not the “Preview Loop Values”.
And this will make sure we only search Pipedrive when the Email Address Exists.
Path A1 - Find Person in Pipedrive
Now we’re ready for our Find Person action - again using the Email Addresses field from our Looping step.
One thing to note below is that I’ve selected “Yes” for Should this step be considered a "success" when nothing is found?
In some cases there might be a match in Pipedrive - and setting this to Yes will ensure the Zap does not error.
Path A2 - Storage Push Value Onto List
Storage is a great way for us to temporarily store data in a Zap to use in later steps or even a different Zap.
In this case - I want to keep a list of the Names, Emails and Phone numbers for the users the team needs to contact.
And I want to collect all of these and post one message to Slack with all the values.
To do this we’re going to use Push Value Onto List as our Storage Action.
We’ll select a “Key” for this list - here I’ve chosen “phoneCalls”.
We just want to make sure this is not a Storage Key we are using in any other Zaps.
And notice we’ve added the same line breaks (and headers) we want to see in our slack message here as well - such as the * for Bolding my text in Slack and the line breaks I want in the message.
This includes the last blank line so there is a break between records in the message that gets posted.
Finally we’ve selected “End of List (if not already in the list)” as the location we’d like this value to be pushed onto the list.
And that’s it for Path A.
This Path will run in a loop for all of our Loop Iterations that have an Email Address - and add the Pipedrive data to our Storage List.
In the end - we’ll have a List of all the Names, Phone and Email addresses we need to contact - ready to be posted into Slack.
That is the message we’ll create in Path B.
Path B Criteria
Since Path B will send our Slack Message - we only want it to run once all the Loops of the email Lookups in Slack have completed.
So we’ll set the Criteria to be when the Loop Iteration is Last Boolean is True.
Meaning Path B will only run on the last iteration of our Loops.
Path B1 - Delay for 1 Minute
Since Path A could be running at the same time as Path B for the last loop iteration - we want to add a short 1 minute Delay For action in Path B to give the final Loop in Path A time to complete and update the List.
Path B2 - Storage Get Values from List
Now we want to retrieve all the items from our Storage List.
To do that we’ll use a Storage - Get List Values action where the Key is the same Key we used in Path A2 - phoneCalls.
For the item format - we’ve used the default - %s and selected to have “New Line” as the Item separator.
Finally - we’ve again selected Yes for this to be a success when nothing is found to avoid any errors.
Path B3 - Filter
We don’t want the Slack message to post if there are no new records found in Pipedrive - so we can add a Filter to only continue when the Output from our Storage step exists.
Path B4 - Post Message in Slack
Now we’re finally ready to post our Slack Message.
I’ve selected to send a Direct Message to myself for the purposes of our example Zap here - but this would work with sending a Channel or Private Channel Message as well.
I’ve included just some brief intro text and then the Output from our Storage step for the Message Text.
Path B5 - Storage Remove Value
The final step is for us to remove the values we have stored at the “phoneCalls” Key - so that we start with an Empty List the next time the Zap triggers.
Running a Live Test
Now we’re ready to turn the Zap ON and run a Live Test!
I’ve sent in the same webhook from the beginning of this post - with 3 email addresses and 2 blank values.
So what do you expect to see in Zap History?
Even though there was only 1 Trigger Event (1 webhook) - we see 5 different Zap Runs in Zap History.
The first thing to note in that screenshot above is that the Task Counts we see in Zap History are overstated.
Basically the Loop and any action steps before the Loop are counted twice in Zap History.
This is only a display issue - the tasks for billing are counted correctly.
For example - if we add up all the Tasks in my screenshot above we get 20 - but my Zaps only used 16 Tasks from a Billing perspective.
If we were to click into each of those Zap Runs - we’d see the one that says 1 task is one of our Blank Records where neither Path Ran.
The runs that say 4 Tasks are the runs where we actually did a lookup in Pipedrive and added the value to Storage.
And the one with 7 tasks is the one that posted our Slack Message.
In essence the Zap forks - and we see one Zap History Entry for each Iteration from the Loop.
And what does our Slack Message look like?
Just like we had wanted. :)
We see 3 entries for the 3 Email Addresses that existed in our trigger data - and no entries for the blanks.
Likewise - our Zap completed without any errors even though 2 of our records were blank in the initial trigger data.
Summary
We often want to do multiple lookups in an App - but the action in Zapier is expecting only one value to lookup at a time.
By using a combination of Looping by Zapier and Storage by Zapier - we can loop through a variable number of records and store data to be used in a final action for the Zap.
I intentionally chose to include some blank or null values in our trigger data in this example to illustrate how we’d account for those null values in our Zap configuration.
If we didn’t have null values - the Paths could have been eliminated from our configuration above and replaced with a Filter.
There are many possible variations on the example above - if you give one a try - I’d love to hear about it in the comments below!