Download attachment by passing file_name instead of sys_id
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-31-2022 12:04 PM
We are able to download an attachment using the sys id by using the below URL in the web browser or postman.
https://servicenow-instance.ourdomain.com/sys_attachment.do?sys_id=21e63dce1fbec118fb5252c7b04cbcd4
Can we download an attachment by querying just with the filename?
I tried: https://servicenow-instance.ourdomain.com/sys_attachment.do?file_name=myfile.xls but it didn't work.
Thanks in advance.
- Labels:
-
Multiple Versions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-31-2022 03:08 PM
This should work, haven't tried with the Attachment API, but works with other tables.
https://servicenow-instance.ourdomain.com/sys_attachment.do?sysparm_query=file_name%3Dmyfile.xls
Aoife
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-19-2022 10:53 PM
Hi Aoife,
Sorry for the delay in response, I was on a vacation and logged back in yesterday.
This did not work for me when I tried it in the browser but yes I am looking for something similar where I just pass the file name and it returns the latest version of it.
Thanks

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-22-2022 03:33 AM
Java sample to download attachment file.
ServiceNowSample.java
package org.hozawa.servicenow.sample.servicenow_sample;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
public class ServiceNowSample {
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
String tableSysId = "b5ac0db09747411086d3b4b3f153afb2"; // sys_id of table to download from (Table sys ID in sys_attachment table)
String filename = "2021-03-28_13-20-01.png"; // name of file to download
AttachmentUtil attachment = new AttachmentUtil();
attachment.getAttachmentByFileName(tableSysId, filename);
}
}
AttachmentUtil.java
package org.hozawa.servicenow.sample.servicenow_sample;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.hozawa.servicenow.sample.servicenow_sample.pojo.SysAttachment;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
public class AttachmentUtil {
public void getAttachmentByFileName(String tableSysId, String filename) {
RestUtil restUtil = new RestUtil();
try {
// get information from sys_attachment table
List<SysAttachment> sysAttachmentList = getAttachmentMetaData(tableSysId, filename);
sysAttachmentList.forEach(s -> {
try {
restUtil.callAttachmentAPI(s.getSysId(), s.getContentType(), "./" + s.getFileName());
} catch (InterruptedException | URISyntaxException | IOException e) {
e.printStackTrace();
}
});
} catch (InterruptedException | URISyntaxException | IOException e) {
e.printStackTrace();
}
}
public List<SysAttachment> getAttachmentMetaData(String tableSysId, String filename) throws InterruptedException, URISyntaxException, IOException {
RestUtil restUtil = new RestUtil();
List<SysAttachment> sysAttachmentList = new ArrayList<>();
JsonNode result = restUtil.callAttachmentMetaAPI(tableSysId, filename);
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
if (result.isArray()) {
ArrayNode array = (ArrayNode) result;
array.forEach(n -> {
SysAttachment sysAttachment = mapper.convertValue(n, SysAttachment.class);
sysAttachmentList.add(sysAttachment);
});
}
return sysAttachmentList;
}
}
RestUtil.java
package org.hozawa.servicenow.sample.servicenow_sample;
import static org.hozawa.servicenow.sample.servicenow_sample.Constants.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.util.Base64;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class RestUtil {
public JsonNode callJsonAPI(String uri) throws InterruptedException, URISyntaxException, IOException {
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(uri))
.header("Authorization", basicAuth(USERNAME, PASSWORD))
.header("Content-type", "application/json")
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
JsonNode root = mapper.readTree(response.body().toString());
return root.at("/result");
}
public JsonNode callTableAPI(String tableName) throws InterruptedException, URISyntaxException, IOException {
return callJsonAPI("https://" + INSTANCENAME + ".service-now.com/api/now/table/" + tableName);
}
public JsonNode callAttachmentMetaAPI(String tableSysId, String tableName) throws InterruptedException, URISyntaxException, IOException {
return callJsonAPI("https://" + INSTANCENAME + ".service-now.com/api/now/attachment?sysparm_query=table_sys_id%3D" + tableSysId + "%5Efile_name%3D" + tableName);
}
public void callAttachmentAPI(String sysId, String contentType, String filePath) throws InterruptedException, URISyntaxException, IOException {
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(
"https://" + INSTANCENAME + ".service-now.com/api/now/attachment/" + sysId + "/file"))
.header("Authorization", basicAuth(USERNAME, PASSWORD))
.header("Content-Type", contentType)
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofFile(Path.of(filePath)));
// int status = response.statusCode();
// System.out.println("status:" + status);
}
private static String basicAuth(String username, String password) {
return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
}
}
Constants.java
package org.hozawa.servicenow.sample.servicenow_sample;
public final class Constants {
public static final String USERNAME = "<user name>";
public static final String PASSWORD = "<password>";
public static final String INSTANCENAME = "<instance name>";
}
SysAttachment.java
package org.hozawa.servicenow.sample.servicenow_sample.pojo;
/**
* Generated using https://www.jsonschema2pojo.org/
*/
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"size_bytes",
"file_name",
"sys_mod_count",
"average_image_color",
"image_width",
"sys_updated_on",
"sys_tags",
"table_name",
"sys_id",
"image_height",
"sys_updated_by",
"download_link",
"content_type",
"sys_created_on",
"size_compressed",
"compressed",
"state",
"table_sys_id",
"chunk_size_bytes",
"hash",
"sys_created_by"
})
public class SysAttachment {
@JsonProperty("size_bytes")
private String sizeBytes;
@JsonProperty("file_name")
private String fileName;
@JsonProperty("sys_mod_count")
private String sysModCount;
@JsonProperty("average_image_color")
private String averageImageColor;
@JsonProperty("image_width")
private String imageWidth;
@JsonProperty("sys_updated_on")
private String sysUpdatedOn;
@JsonProperty("sys_tags")
private String sysTags;
@JsonProperty("table_name")
private String tableName;
@JsonProperty("sys_id")
private String sysId;
@JsonProperty("image_height")
private String imageHeight;
@JsonProperty("sys_updated_by")
private String sysUpdatedBy;
@JsonProperty("download_link")
private String downloadLink;
@JsonProperty("content_type")
private String contentType;
@JsonProperty("sys_created_on")
private String sysCreatedOn;
@JsonProperty("size_compressed")
private String sizeCompressed;
@JsonProperty("compressed")
private String compressed;
@JsonProperty("state")
private String state;
@JsonProperty("table_sys_id")
private String tableSysId;
@JsonProperty("chunk_size_bytes")
private String chunkSizeBytes;
@JsonProperty("hash")
private String hash;
@JsonProperty("sys_created_by")
private String sysCreatedBy;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("size_bytes")
public String getSizeBytes() {
return sizeBytes;
}
@JsonProperty("size_bytes")
public void setSizeBytes(String sizeBytes) {
this.sizeBytes = sizeBytes;
}
@JsonProperty("file_name")
public String getFileName() {
return fileName;
}
@JsonProperty("file_name")
public void setFileName(String fileName) {
this.fileName = fileName;
}
@JsonProperty("sys_mod_count")
public String getSysModCount() {
return sysModCount;
}
@JsonProperty("sys_mod_count")
public void setSysModCount(String sysModCount) {
this.sysModCount = sysModCount;
}
@JsonProperty("average_image_color")
public String getAverageImageColor() {
return averageImageColor;
}
@JsonProperty("average_image_color")
public void setAverageImageColor(String averageImageColor) {
this.averageImageColor = averageImageColor;
}
@JsonProperty("image_width")
public String getImageWidth() {
return imageWidth;
}
@JsonProperty("image_width")
public void setImageWidth(String imageWidth) {
this.imageWidth = imageWidth;
}
@JsonProperty("sys_updated_on")
public String getSysUpdatedOn() {
return sysUpdatedOn;
}
@JsonProperty("sys_updated_on")
public void setSysUpdatedOn(String sysUpdatedOn) {
this.sysUpdatedOn = sysUpdatedOn;
}
@JsonProperty("sys_tags")
public String getSysTags() {
return sysTags;
}
@JsonProperty("sys_tags")
public void setSysTags(String sysTags) {
this.sysTags = sysTags;
}
@JsonProperty("table_name")
public String getTableName() {
return tableName;
}
@JsonProperty("table_name")
public void setTableName(String tableName) {
this.tableName = tableName;
}
@JsonProperty("sys_id")
public String getSysId() {
return sysId;
}
@JsonProperty("sys_id")
public void setSysId(String sysId) {
this.sysId = sysId;
}
@JsonProperty("image_height")
public String getImageHeight() {
return imageHeight;
}
@JsonProperty("image_height")
public void setImageHeight(String imageHeight) {
this.imageHeight = imageHeight;
}
@JsonProperty("sys_updated_by")
public String getSysUpdatedBy() {
return sysUpdatedBy;
}
@JsonProperty("sys_updated_by")
public void setSysUpdatedBy(String sysUpdatedBy) {
this.sysUpdatedBy = sysUpdatedBy;
}
@JsonProperty("download_link")
public String getDownloadLink() {
return downloadLink;
}
@JsonProperty("download_link")
public void setDownloadLink(String downloadLink) {
this.downloadLink = downloadLink;
}
@JsonProperty("content_type")
public String getContentType() {
return contentType;
}
@JsonProperty("content_type")
public void setContentType(String contentType) {
this.contentType = contentType;
}
@JsonProperty("sys_created_on")
public String getSysCreatedOn() {
return sysCreatedOn;
}
@JsonProperty("sys_created_on")
public void setSysCreatedOn(String sysCreatedOn) {
this.sysCreatedOn = sysCreatedOn;
}
@JsonProperty("size_compressed")
public String getSizeCompressed() {
return sizeCompressed;
}
@JsonProperty("size_compressed")
public void setSizeCompressed(String sizeCompressed) {
this.sizeCompressed = sizeCompressed;
}
@JsonProperty("compressed")
public String getCompressed() {
return compressed;
}
@JsonProperty("compressed")
public void setCompressed(String compressed) {
this.compressed = compressed;
}
@JsonProperty("state")
public String getState() {
return state;
}
@JsonProperty("state")
public void setState(String state) {
this.state = state;
}
@JsonProperty("table_sys_id")
public String getTableSysId() {
return tableSysId;
}
@JsonProperty("table_sys_id")
public void setTableSysId(String tableSysId) {
this.tableSysId = tableSysId;
}
@JsonProperty("chunk_size_bytes")
public String getChunkSizeBytes() {
return chunkSizeBytes;
}
@JsonProperty("chunk_size_bytes")
public void setChunkSizeBytes(String chunkSizeBytes) {
this.chunkSizeBytes = chunkSizeBytes;
}
@JsonProperty("hash")
public String getHash() {
return hash;
}
@JsonProperty("hash")
public void setHash(String hash) {
this.hash = hash;
}
@JsonProperty("sys_created_by")
public String getSysCreatedBy() {
return sysCreatedBy;
}
@JsonProperty("sys_created_by")
public void setSysCreatedBy(String sysCreatedBy) {
this.sysCreatedBy = sysCreatedBy;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-22-2022 10:36 AM
Hi Hitoshi,
I see you used Java 11 APIs(java.net.http.HttpClient) and also the attachment REST API provided by ServiceNow. The problem here is that we are not authorized to use the REST API.
That is the reason I was looking for a direct URL to the latest excel file, if you see my initial post. Though I appreciate your effort in helping me solve this.
Is there any way we can pass the filename as a parameter in the URL and retireve the latest parameter or the list of tables it exists in and then make a second call to get it from the correct table by mentioning the table_sys_id and filename?
Thanks,
Ovin