Managing content Tags in Box using the CLI
Use case
This article was inspired by a question on our forum:
I would like to maintain the tags assigned to Box in bulk, is there any good solution? I was considering a way to use Box CLI, but the description of the CSV template does not mention tags, so I am looking for a solution.
I want to change the tags assigned to files in bulk with CLI. (e.g. tagA→tagB)
The tools
For this use case, the Box CLI is in fact the appropriate tool for the job. However you could easily integrate tags related features into your applications using any of our SDK's, or even manage tags directly using our REST API.
For this demo I'm using the Box CLI configured as a JWT application. This implies there is a service user which has to impersonate --as-user
myself.
To make it easier to display in a blog format, I'll use CSV file format, forcing me to process the file using common tools such as Excel or the sed
operating system command. However the Box CLI can also work with JSON format.
To get started with our Box CLI, you can take a look at this guide.
Finally I'm using MacOS so I do have access to sed
and my shell is zShell. Of course Box CLI can also be used with PowerShell, Bash, etc.
Experiment with what ever you feel comfortable with.
Searching for tags
Since I have Box CLI configured as a JWT app, let's check the service user and the user I need to put in the --as-user
flag.
❯ box users:get --csv --fields id,name,login
type,id,name,login
user,20130487697,JWT,AutomationUser_1827756_bs5C1GfCgv@boxdevedition.com
And the list of users available:
❯ box users --csv --fields id,name,login
type,id,name,login
user,18662105676,Administrator,AppUser_1715931_Il2dcyHuqu@boxdevedition.com
user,18662356345,Administrator,AppUser_1715931_vt8XOps1Ff@boxdevedition.com
user,18661971368,Administrator,AppUser_1715931_xSifhdw6W7@boxdevedition.com
user,22240548078,Investment User,barduinor+inv@gmail.com
user,22240405099,Wealth User,barduinor+we@gmail.com
user,22240545678,Wholesale User,barduinor+wh@gmail.com
user,18622116055,Rui Barbosa,barduinor@gmail.com
The content for which I want to manage the tags is under user 18622116055
, so I'll use this user id on the --as-user
flag.
Now let's list all files tagged with TAG-A
.
Please note that the search engine is querying an indexed database of the content and it can take a few minutes to index new content, just in case you are searching for content that was just created.
❯ box search "TAG-A" --as-user 18622116055 \
--content-types tags \
--csv --fields type,id,name,tags
type,id,name,tags
file,1016206416109,sample1.cr2,"[""TAG-D"",""TAG-A""]"
file,1016197618492,sample1.heic,"[""TAG-E"",""TAG-A""]"
file,1016203876842,023A9785.CR3,"[""TAG-C"",""TAG-A""]"
The --content-type tags
reduces the scope of the search to only tags, as opposed to search for the query string in name, description and content.
The --csv --fields type,id,name,tags
, tells the Box CLI to output in CSV format and only show type, id, name, and tags.
I could also use the --json
to get a JSON output:
❯ box search "TAG-A" --as-user 18622116055 \
--content-types tags \
--json --fields type,id,name,tags
[
{
"type": "file",
"id": "1016206416109",
"name": "sample1.cr2",
"tags": [
"TAG-D",
"TAG-A"
]
},
{
"type": "file",
"id": "1016197618492",
"name": "sample1.heic",
"tags": [
"TAG-E",
"TAG-A"
]
},
{
"type": "file",
"id": "1016203876842",
"name": "023A9785.CR3",
"tags": [
"TAG-C",
"TAG-A"
]
}
]
Manipulating content tags
Now suppose I want to add FOOBAR
for the first file sample.cr2
, I could try this:
❯ box files:update 1016206416109 \
--as-user 18622116055 \
--tags "FOOBAR" \
--csv --fields type,id,name
type,id,name
file,1016206416109,sample1.cr2
The end result is:
❯ box search "TAG-A" --as-user 18622116055 \
--content-types tags \
--csv --fields type,id,name,tags
type,id,name,tags
file,1016206416109,sample1.cr2,"[""FOOBAR""]"
file,1016197618492,sample1.heic,"[""TAG-E"",""TAG-A""]"
file,1016203876842,023A9785.CR3,"[""TAG-C"",""TAG-A""]"
Probably not what you expected, the tags update must include all the tags that you want associated with he content. In practice what we did was to replace all existing tags, if any, by the tag FOOBAR
Let's put back the original tags for file sample1.cr2
❯ box files:update 1016206416109 \
--as-user 18622116055 \
--tags "TAG-D,TAG-A" \
--csv --fields type,id,name
type,id,name
file,1016206416109,sample1.cr2
And check the results:
❯ box search "TAG-A" --as-user 18622116055 \
--content-types tags \
--csv --fields type,id,name,tags
type,id,name,tags
file,1016206416109,sample1.cr2,"[""TAG-A"",""TAG-D""]"
file,1016197618492,sample1.heic,"[""TAG-E"",""TAG-A""]"
file,1016203876842,023A9785.CR3,"[""TAG-C"",""TAG-A""]"
Replacing TAG-A with TAG-B
Since we need the original complete tags of each file, we need to first dump the existing content tags into a file, change TAG-A
with TAG-B
, and then update the content with the new set of tags.
Saving to a file is simple, we can use the operating system operator >
piping it to a new file, or the --save-to-file-path
flag.
❯ box search "TAG-A" --as-user 18622116055 \
--content-types tags \
--csv --fields type,id,name,tags > tag-a-content.csv
Let's display the content:
❯ cat tag-a-content.csv
type,id,name,tags
file,1016206416109,sample1.cr2,"[""TAG-A"",""TAG-D""]"
file,1016197618492,sample1.heic,"[""TAG-E"",""TAG-A""]"
file,1016203876842,023A9785.CR3,"[""TAG-C"",""TAG-A""]"
We can import this into Excel, and it will look like this:
You may have noticed the uncommon format of the tags in excel, and from our example above we know that the update must be set of comma separated tags. So we need to "massage" this file to be able to update the content in bulk.
Since I'm on a mac, I can just use the sed
command. Using Excel you can do some clever find and replace, or use a formula to change the tag column.
❯ sed -e "s/TAG-A/TAG-B/g" \
-e "s/\[\"\"//g" \
-e "s/\"\"\]//g" \
-e "s/\"\"\,\"\"/\,/g" \
./tag-a-content.csv > tag-a-content-modified.csv
With the result:
❯ cat tag-a-content-modified.csv
type,id,name,tags
file,1016206416109,sample1.cr2,"TAG-B,TAG-D"
file,1016197618492,sample1.heic,"TAG-E,TAG-B"
file,1016203876842,023A9785.CR3,"TAG-C,TAG-B"
Now that we replaced TAG-A
with TAG-B
, and have the correct format, we can just feed this file to the update command of Box CLI, using the --bulk-file-path
flag.
❯ box files:update --as-user 18622116055 \
--bulk-file-path ./tag-a-content-modified.csv \
--csv --fields type,id,name,tags
[========================================] 100% | 3/3
type,id,name
file,1016206416109,sample1.cr2
file,1016197618492,sample1.heic
file,1016203876842,023A9785.CR3
All bulk input entries processed successfully.
The files have beed immediately updated:
But remember search might take a few minutes to index the new tag.
Searching for TAG-B
:
❯ box search "TAG-B" --as-user 18622116055 \
--content-types tags \
--csv --fields type,id,name,tags
type,id,name,tags
file,1016206416109,sample1.cr2,"[""TAG-D"",""TAG-B""]"
file,1016197618492,sample1.heic,"[""TAG-E"",""TAG-B""]"
file,1016203876842,023A9785.CR3,"[""TAG-C"",""TAG-B""]"
We're done!
What to learn more?
Visit our developer documentation site, and follow us in medium, and twitter to stay up-to-date.
Cheers!