Cli to generate protocol buffers - protoc

In my test.proto file I have as below, i.e. no field inside message HTML, how do I set a value for the _html field of message Page?
message HTML{
enum Type {
NO_TYPE = 0;
HTML5 = 1;
XHTML = 2;
}
}
message Page{
optional HTML _html = 1;
}
How can I set the values?
echo _html : **???** | protoc --encode=Page test.proto > binary.data
https://medium.com/#at_ishikawa/cli-to-generate-protocol-buffers-c2cfdf633dce

How can I set the values?
you can't when it is defined like you have shown. The message HTML only contains a definition of an enum but no actual fields. You can either add a field in the message HTML, or define the type in Page as HTML.Type instead of just HTML:
test.proto:
message HTML{
enum Type {
NO_TYPE = 0;
HTML5 = 1;
XHTML = 2;
}
}
message Page{
optional HTML.Type _html = 1;
}
and then create a file test.txt:
_html: HTML5
you can create a binary file like this:
protoc --experimental_allow_proto3_optional --encode Page test.proto < test.txt > binary.data
and decode it :
protoc --experimental_allow_proto3_optional --decode Page test.proto < binary.data
The last command prints:
_html: HTML5
Apart from the enum definition, the HTML message is an Empty message, which even exists as a predefined message:
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
// or the response type of an API method.
// The JSON representation for Empty is empty JSON object {}.
message Empty {}

Related

How get attachments in outlook plugin?

Hi how can i get attachments and send it to my java server?
in docs its say:
var item = Office.context.mailbox.item;
var options = {asyncContext: {currentItem: item}};
item.getAttachmentsAsync(options, callback);
function callback(result) {
if (result.value.length > 0) {
for (i = 0 ; i < result.value.length ; i++) {
result.asyncContext.currentItem.getAttachmentContentAsync(result.value[i].id, handleAttachmentsCallback);
}
}
}
function handleAttachmentsCallback(result) {
// Parse string to be a url, an .eml file, a base64-encoded string, or an .icalendar file.
switch (result.value.format) {
case Office.MailboxEnums.AttachmentContentFormat.Base64:
// Handle file attachment.
break;
case Office.MailboxEnums.AttachmentContentFormat.Eml:
// Handle email item attachment.
break;
case Office.MailboxEnums.AttachmentContentFormat.ICalendar:
// Handle .icalender attachment.
break;
case Office.MailboxEnums.AttachmentContentFormat.Url:
// Handle cloud attachment.
break;
default:
// Handle attachment formats that are not supported.
}
}
But i have several errors witch this example.
first is item.getAttachmentsAsync is not a function
then im tried to use
result.asyncContext.currentItem.getAttachmentContentAsync(item.attachments[2].id, handleAttachmentsCallback);
but its never called calback
How can i get attachments and send them by XMLHttpRequest to my server?
Most likely what is happening is that you are trying this code on a read item. The getAttachmentsAsync fn only exists in compose mode, so you would see the error above if you are not composing an email. For read emails you should be able to just access the attachments property Office.context.mailbox.item.attachments (https://learn.microsoft.com/en-us/javascript/api/outlook/office.attachmentdetails?view=outlook-js-preview)
Read Mode:
https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/get-attachments-of-an-outlook-item?view=outlook-js-preview
Compose Mode:
https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/add-and-remove-attachments-to-an-item-in-a-compose-form?view=outlook-js-preview
However, as mentioned in Jadams answer, getAttachmentContentAsync IS supported in Read Mode, and you can get that to the the Base64 encoding of attachments. (the first link will be updated soon to reflect this)

Returning Html as Response from grpc-gatway

Is there is a way i can return the content-type= " application/html" from the server.
grpc-gateway returning the response in key-value pair and browsers are unable parse it.
Proto Defination:
rpc Create (RegId) returns (Resp);
message RegId {
string id = 1;
}
message Resp {
string response = 1;
}
Returning response as HTML but in key-value pair.
How can i just return the html
{"response":"\u003chtml\u003e\u003cb\u003e Hey Developer \u003c/b\u003e\u003c/html\u003e"}
Try to use runtime.HTTPBodyMarshaler (https://github.com/grpc-ecosystem/grpc-gateway/issues/1881#issuecomment-797384040) for your grpc server, for example define runtime.ServeMuxOption in this way
runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{&runtime.JSONPb{EmitDefaults: true}})

Unable to view PDF attached with ServiceNow table records

I am able to successfully attach PDF file with ServiceNow table record using GlideSysAttachment API and attachment.write() function in script, however whenever I download and try to open same, I get the error shown in below screenshot.
Code snippet
(function execute() {
try{
var rec = new GlideRecord('incident');
var attachment = new GlideSysAttachment();
var incidentSysID = incident.number;
rec.get(incidentSysID);
var fileName = 'Test_Incident.pdf';
var contentType = 'application/pdf'; // Also tried with contentType as 'text/pdf'
var content = pdf_content;
var agr = attachment.write(rec, fileName, contentType, content);<br>
gs.info('The PDF attachment sys_id is: ' + agr);
}catch(err){
gs.log('Got Error: ' + err);
gs.info(err);
}
})()
I also tried "AttachmentCreator" with ecc_queue within script but same error occurs. Below is code for it.
(function execute()
{var attCreator = new GlideRecord('ecc_queue');
attCreator.agent = "AttachmentCreator";
attCreator.topic = "AttachmentCreator";
attCreator.name = "Test.pdf" + ":" + "text/pdf";
//Also tried, "Test.pdf:application/pdf"
attCreator.source = "incident"+":"+ incident.number;
// Record Table name and sys_id of the particular record
var content = pdf_content; // pdf_content is any string variable
var stringUtil = new GlideStringUtil();
var base64String = stringUtil.base64Encode(content);
var isValid=GlideStringUtil.isBase64(base64String);
var base64String= gs.base64Encode(content);
gs.info("Is valid base64 format in ecc_queue ? "+ isValid);
attCreator.payload = base64String; //base64 content of the file
attCreator.insert();
})()
I am able to attach and view excel and word files with similar scripts without any issues. I have checked system properties for attachments but everything looks fine. I am able to view the PDF file uploaded from UI to particular table records however not the one I attach via REST API or scripts.
I have also tried sending encoded data as bytes, base64 or simple string but nothing seems to work. I don't get any errors and attachment id is returned each time on creation of attachment.
After modifying my code slightly for above functions w.r.t scoped application instead of global; I got some information from logs when I debug:
05:38:38.411 Security restricted: File type is not allowed or does not match the content for file Test.pdf
05:38:38.410 Security restricted: MIME type mismatch for file: Test.pdf. Expected type:application/pdf, Actual type: text/plain
05:38:38.394 App:XYZ App x_272539_xyz_ap: Is valid base64 format in ecc_queue ? true
First a comment: This line in your code is accidentally working -- make sure you understand that a task number is not the object sys_id
var incidentSysID = incident.number; // should be incident.sys_id
Next, it's unclear where the PDF content is coming from. IF your complete code is listed, I would expect the errors given as you have noted that pdf_content is "any string variable."
ServiceNow does have a the capability to create a PDF from an HTML argument.
Generating a PDF from HTML
Here's a helpful blog post for getting a PDF (Platform generated) of an existing record:
Love PDF? PDF loves you too

Proper way to errors response in GRPC?

I try to find out the way to report server errors via grpc. What I want to achieve is errors that are verbose and static defined enough to tell clients what actually happened.
Imagine I have the next request:
message UpdateEmailRequest {
string email = 1;
}
message UpdateEmailResponse {
}
Then I was trying to make errors more verbose because status codes don't tell clients about error details. You could use FieldViolation, but it only specifies the field, not the error in the static way. You could provide Description to these FieldViolations but clients need to either deal with string errors and somehow map them to internal client errors OR clients display these errors directly, which doesn't work in some cases because business logic can vary based on the error type.
What I've invented is:
message UpdateEmailResponse {
enum ErrorCode {
UNKNOWN_ERROR = 0;
INVALID_EMAIL_LENGTH = 1;
INVALID_EMAIL_FORMAT = 2;
INVALID_EMAIL_TEMPORARY_MAIL_NOT_ALLOWED = 3; //temporary mail services
INVALID_EMAIL_ALIAS = 4; // email is alias or redirect, not the actual email
INVALID_EMAIL_FORBIDDEN_WORDS = 5; // for email with bad language
...
}
message Body {}
oneof response {
ErrorCode error_code = 1;
Body body = 2;
}
}
This way you could let the clients know about specific errors combined with status codes, but it doesn't use the out-of-box FieldViolations and it looks like non-grpc way to handle errors.
Other solution is to embed json with error code (which I can still have defined inside the request entity) and error msg inside the FieldViolations's Description, but again, it looks like non-grpc way.
So, I'm stuck here with errors in grpc, could you tell me the proper way to do it?
Thanks.

How does wep api return a content type of html although I have only defined a JsonFormatter?

In my Application_Start:
var jsonFormatter = new JsonMediaTypeFormatter();
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
My default url:
[HttpGet]
[Route("~/")]
public HttpResponseMessage Index()
{
var stream = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Views\Home\Index.html"));
var content = new StreamContent(stream);
return new HttpResponseMessage() { Content = content };
}
The content is of type "text/html" but I have not set it in the response.Headers.ContentType but still the html file is correctly returned although there is not something like a html content negotiator and actually I assumed the action would return the html file as json or an error would occur but everything worked fine.
Why is that?
After googling a while I found this explanation:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
Any HTTP/1.1 message containing an entity-body SHOULD include a
Content-Type header field defining the media type of that body. If and
only if the media type is not given by a Content-Type field, the
recipient MAY attempt to guess the media type via inspection of its
content and/or the name extension(s) of the URI used to identify the
resource. If the media type remains unknown, the recipient SHOULD
treat it as type "application/octet-stream".
So my "browser" is inspecting the URI of the resource which ends with .HTML and therefore its treated as content-type "text/html" :-)

Resources