I have been working on parsing email using golang. I am now in the part of extracting the attachments. I have looked into golang lib MIME and MIME/multipart. But it does not have any methods or function to do this.
What specifically I want to do is: Example
I have an email file with attachments file1.txt, file2.pdf, and file3.png. I have successfully parsed the email body. Now I want to extract the attachment and save them on a separate directory. I have searched all part of golang including MIME and MIME/multipart. They seem to not have this functionality. Can golang do this? if Yes any hint or clue please.
I found a solution to this that uses the parsemail function from DusanKasan
import (
"github.com/DusanKasan/parsemail"
)
func readEmail() error {
b := getYourEmail()
email, err := parsemail.Parse(bytes.NewBuffer(b))
if err != nil{
return err
}
for _, a := range email.Attachments{
// do stuff with attachment
}
}
I think firstly you should find the boundary of:
Content-Type: multipart/mixed; boundary={sample-boundary}
Then you split the email by that sample-boundary.
And finally you get the base64 encoding part of attachment.
I'm current working on this. I'll be back when I'm done.
Related
How do I in Mimekit send an email having the html body base64 encoded?
In code I first create the entire body as a MimeEnitity including attachments using the BodyBuilder. Then I create the MimeMessage to be sent having the body.
The first thing you'll need to do is to locate the HTML body part.
A quick hack might look something like this:
var htmlBody = message.BodyParts.OfType<TextPart> (x => x.IsHtml).FirstOrDefault ();
Then you'll need to set the Content-Transfer-Encoding:
htmlBody.ContentTransferEncoding = ContentEncoding.Base64;
That's it.
I am trying to upload files to Google drive using
RestAPI in Delphi.Every thing is working fine but files are Uploading into Google drive with Untitled name.
Below is code i written for uploading into drive.
local_filename:= 'D:/Capture.jpg';
{$ENDIF}
RESTResponseDataSetAdapter.AutoUpdate :=false;
RESTRequest.Params.Clear;
RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.AddParameter('application/json; charset=utf-8','{"title": "Capture.jpg"}',TRESTRequestParameterKind.pkREQUESTBODY);
RESTClient.BaseURL := 'https://www.googleapis.com/upload/drive/v2';
RESTRequest.Resource := '/files?uploadType=multipart';
upload_stream := TFileStream.Create(local_filename,fmOpenRead);
upload_stream.Position := 0
RESTRequest.Addbody(upload_stream, TRESTContentType.ctIMAGE_JPEG);
RESTRequest.Execute;
Can some one suggest how to give a file name/ upload the file with the same name to google drive.
AddBody() appears to supercede AddParameter(), so you would be wiping out your metadata JSON. This is stated in the AddBody() documentation:
Generally, a call to AddBody replaces any previous value of the body parameter. However, if you pass ABodyContent as a string, the specified value is appended, and the resulting request contains several body parameters
The JSON metadata and the JPG file need to be sent together in the request body, in multipart/related format. However, looking at TRESTRequest, I don't see an easy way to send requests in that format (I may be wrong here). You might have to put the entire multipart data in a single TStream and pass that to AddBody() with a ContentType of TRESTContentType.ctMULTIPART_RELATED. If you try to add the various pieces as separate parameters, it won't send the right content type:
A single-parameter request uses application/x-www-form-urlencoded, while a multiple-parameter request uses multipart/mixed instead.
Check Google Drive REST API reference
https://developers.google.com/drive/v2/web/manage-uploads#multipart.
You have to send "metadata". There are 2 options. You complete that simple upload and then call another request to update metada of this file. Or you can do multi-part upload and add a parameter.
This one should work but it seems that REST request does not support this method.
RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Params.AddItem('metadata', '{"title": "YourFileName.dat"}', TRESTRequestParameterKind.pkREQUESTBODY, [], TRESTContentType.ctAPPLICATION_JSON);
So the solution is to update metadata after your request
var
s: string
RESTRequest1.Response.GetSimpleValue('id', s);
RESTRequest1.Params.Clear;
RESTClient1.BaseURL := 'https://www.googleapis.com/drive/v2/files/'+s;
RESTRequest1.Resource := '';
RESTRequest1.Method:=TRESTRequestMethod.rmPUT;
RESTRequest1.AddBody('{"title": "Capture.jpg"}', TRESTContentType.ctAPPLICATION_JSON);
RESTRequest1.Execute;
I am making http requests using Go.
request, err := http.NewRequest("GET", url, nil)
This request, if successful, returns a response.
response, err := client.Do(request)
After receiving a response, I want to save the content.
content, err := ioutil.ReadAll(response.Body)
ioutil.WriteFile(destination, content, 0644)
I looked at the Headers of the responses.
response.Header.Get("Content-Type")
I saw the majority are already UTF-8 encoded, which is good. But there are some that have different encodings. I know Go has built in unicode support. Does that mean that if I write, for example, the content of a big-5 encoded page, it will be automatically converted to utf-8? Or do I need to manually decode using the big-5 encoding and re-encode using utf-8?
Basically, I want to ensure that everything that gets written is utf-8 encoded. What is the best way to achieve this?
Thanks!
What ioutil.ReadAll reads will be written with ioutil.WriteFile without any conversions whatsoever.
If you want to force UTF-8 encoded you will have to do the de-/encoding yourself, e.g. with the help of golang.org/x/text/encoding{,/charmap} and/or the unicode/utf{8,16} packages.
Be prepared for all sorts of ugliness and a lot of pain.
I have the following code, which tries to send a mail with a .pdf file attached. This .pdf is located in my Google drive.
var files = DriveApp.getFilesByName('file_test.pdf');
GmailApp.sendEmail(email, subject, message, {attachments:files[0]});
I've found that "getFilesByName" returns an array, so that's why I'm using files[0], but it's still not working. I don't know how to debug it, so when I'm testing my code, I am able to send the mail, but I receive it with no attached files.
When you use getFilesByName you are receiving a FileIterator, so you should use the hasNext() and next() functions to retrieve your file.
var files = DriveApp.getFilesByName('file_test.pdf');
if(files.hasNext()){
var file = files.next();
GmailApp.sendEmail(email, subject, message, {attachments:file});
}
In the GmailApp docs, they use the getAs() function on the file to return it as a PDF, this may or may not be necessary in your case.
See:
https://developers.google.com/apps-script/reference/gmail/gmail-app#sendEmail(String,String,String,Object)
https://developers.google.com/apps-script/reference/drive/drive-app
I am sending mail to users via mandrill and I using both smtp and mandrill api to send.
Content of the mail is rendered go template (.tpl)
When I put template like
Hi {{.name}},
<br/>
This is support.
<br/>
it sends via mandrill api ok, but is visible when I send via smtp,
when use template like ( <br/> replaced with \n)
Hi {{.name}},
This is support.
mandrill ignores that and shows everything in one line but smtp shows ok newlines.
What is a solution for this ?
I am rendering template like
frame, err := template.New("foo").Parse( *templateString )
if err != nil {
return nil, err
}
var doc bytes.Buffer
frame.Execute( &doc, *parameters )
temp := doc.String()
Are you sending the mail as HTML? If so, you can wrap everything in the <pre> tag.
If you're not using HTML, setting this header should help: Mime-Type: text/plain
Also, try changing your newlines from \n to \r\n.