Is there any way to get the files from some external source (API) and attach them in the new email through Outlook Add-in using OfficeJs - outlook

Is there any way to get the files from some external source (API) and attach them in the new email through Outlook Add-in using OfficeJs apart from Share point online (Office365) and OneDrive.
Solution approach for implementing attachments functionality from the add-in for external source files and emails

Yes, there is. You may be interested in the addFileAttachmentAsync method which adds a file to a message or appointment as an attachment. The addFileAttachmentAsync method downloads the file at the specified URI and attaches it to the item in the compose form.
Office.context.mailbox.item.addFileAttachmentAsync(
`https://webserver/picture.png`,
'picture.png',
{ asyncContext: null },
function (asyncResult) {
if (asyncResult.status === Office.AsyncResultStatus.Failed){
write(asyncResult.error.message);
} else {
// Get the ID of the attached file.
const attachmentID = asyncResult.value;
write('ID of added attachment: ' + attachmentID);
}
});
See Manage an item's attachments in a compose form in Outlook for more information.

Related

Communication between OnMessageSend event and the add-in (Outlook)

The case concerns the Outlook add-in, namely the communication between the OnMessageSend event and the add-in.
Short description:
The user is authorized in an external service. After logging in, he receives a 'Token' that is used in communication between the add-in and the external service. The token is stored in the cookies.
Add-in is designed for Windows platform.
The use of the OnMessageSend event is described here
It looks like the OnMessageSend event handling is performed regardless of the environment in which the add-in is running. So I can't read the cookies that my add-on has saved (communication via localStorage also doesn't work). Unless I am wrong and it is otherwise.
Problem:
My problem is that in the handling of the OnMessageSend event I have to do a POST to an external service, to do this I need a 'Token' that has been saved in cookies by an add-in.
Is there a way to communicate between the add-in and the OnMessageSend event handler?
How can I pass a 'Token' from the add-in to the OnMessageSend event handler?
Thank you in advance for any hints
It is working for me. Use Office.context.mailbox.item.sessionData.setAsync in your Taskpane JS and then fetch using Office.context.mailbox.item.sessionData.getAsync in your launchevent.js
let oData = JSON.stringify(objData);
//console.log(oData);
Office.context.mailbox.item.sessionData.setAsync("bookingObject", oData, function (asyncResult) {
if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
//console.log("sessionData.setAsync succeeded");
}
else {
console.log("Failed to set sessionData. Error: " + JSON.stringify(asyncResult.error));
}
});
Office.context.mailbox.item.sessionData.getAsync("bookingObject", function (asyncResultBO) {
if (asyncResultBO.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`BO Error:: ${asyncResultBO.error.message}`);
event.completed();
return;
}
const bookingObjectAllData = JSON.parse(asyncResultBO.value);
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) { if (item.IsAddon == false) { ResourceIds = ResourceIds + item.ResourceId + ","; } });
originalAppointment.ResourceIds = ResourceIds;
result = checkRoomAvailabilityOutlook(originalAppointment.ResourceIds, originalAppointment.start, originalAppointment.end);

Outlook Web App: Retrieve contacts

I'm working on developing outlook web addin which runs on both outlook365 and outlook.com. I have a requirement to create, read and update contacts using that web addin. Below is the sample which add current user to To field of an email.
function addToRecipients() {
var item = Office.context.mailbox.item;
var addressToAdd = {
displayName: Office.context.mailbox.userProfile.displayName,
emailAddress: Office.context.mailbox.userProfile.emailAddress
};
if (item.itemType === Office.MailboxEnums.ItemType.Message) {
Office.cast.item.toMessageCompose(item).to.addAsync([addressToAdd]);
} else if (item.itemType === Office.MailboxEnums.ItemType.Appointment) {
Office.cast.item.toAppointmentCompose(item).requiredAttendees.addAsync([addressToAdd]);
}
}
Can anyone point out me how i can retrieve the outlook contacts using outlook web addin ?
Thanks
Yes, makeEwsRequestAsync API is one way to do it with JS API.

Office Outlook Add-in- Adding an attachment from a secure location

I'm adding an "Add attachment" command as part of an Office Outlook add-in.
I want to find a way to add file from a URL with authorization.
I thought downloading it with ajax and then saving it from a blob but looks like the command won't support it.
My code testing it that fails:
const text = 'attachment content';
const blob = new Blob([text], {type: 'text/plain'});
const attachmentURI = window.URL.createObjectURL(blob);
Office.context.mailbox.item.addFileAttachmentAsync(
attachmentURI,
'file.txt',
{ asyncContext: null },
function (asyncResult) {
if(asyncResult.status == Office.AsyncResultStatus.Failed){
console.log('error adding attachment: ' + asyncResult.error.message);
}
else {
const attachmentID = asyncResult.value;
console.log('added attachment: ' + attachmentID);
}
}
);
Any suggestions on saving an attachment from a URL with permissions?
Function documentation:
https://dev.office.com/docs/add-ins/outlook/add-and-remove-attachments-to-an-item-in-a-compose-form
If you are trying to attach a local file from the user's PC to the email then unfortunately you cannot do so since of course this is JavaScript. The attachment methods in the Outlook Add-in API can only deal with web-based files. You would need a web form or other mechanism to upload the file to your web service to an accessible URI location which you can then point to with the addFileAttachmentAsync method. The ASP.NET Web API would be one alternative to implement your web service in.
In addFileAttachmentAsync the attachmentURI parameter is sent to the Server (in OWA's case), or to the Outlook App (desktop Outlook). Then, either the Server or Outlook goes and downloads the file, and attaches it to the e-mail. If OWA/Outlook can't reach the URI that you provide, then it won't work.

Detecting Gmail attachment downloads

Is there a way to detect if a particular file that is being downloaded is a Gmail attachment?
I am looking for a way to write a Greasemonkey script which would help me organize the downloads, based on their download sources, say Gmail email attachments would have a different behavior from other stuff.
So far, I've found out that attachments redirect to https://mail-attachment.googleusercontent.com/attachment/u/0/ , which I guess is not sufficient.
EDIT
Since an add-on would be more powerful than a userscript, I've decided to pursue the Add On idea. However, the problem of detection remains unsolved.
This is too complicated for just one question; it has at least these major parts:
Do you want to redirect downloads when the user clicks, or automatically download select files? Clarify the question.
Your GM script must identify the appropriate download links, and on which pages, and for which views? For gMail, this is not a trivial task, and the question needs to be clearer. It's worthy of a whole question just on this issue given the variety of views and AJAX involved.
Once identified, the script probably needs to intercept clicks on those links. (Depends on your goal (clarify!) and what the Firefox extension can do.)
Greasemonkey needs to interact with an extension that either intercepts the user-initiated download, or allows for an automatic download. I've detailed the auto-download approach, below.
Once your script has identified the appropriate file URLs and/or links (Open a new question for more help with that, and include pictures of the types of pages and links you want.), it can interface with a Firefox add-on, like the one below, to automatically save those files.
Automatically saving files from Greasemonkey with the help of an additional Add-on:
WARNING: The following is a working proof of concept for education only. It has no security features, and if you use it as-is, for actual surfing, some webpage or script writer or extension writer will use it to completely pwn your computer.
If you use the Add-on builder or SDK to install or "Test" the DANGER. DANGER. DANGER. File download utility,
Then you can use a Greasemonkey script, like this, to automatically save files:
// ==UserScript==
// #name _Call our File download add-on to trigger a file download.
// #include https://mail.google.com/mail/*
// #include https://stackoverflow.com/questions/14440362/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// #grant GM_addStyle
// ==/UserScript==
/*- The #grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
var fileURL = "http://userscripts.org/scripts/source/29222.user.js";
var savePath = "D:\\temp\\";
var extensionLoaded = false;
window.addEventListener ("ImAlivefromExtension", function (zEvent) {
console.log ("The test extension appears to be loaded!", zEvent.detail);
extensionLoaded = true;
} );
window.addEventListener ("ReplyToDownloadRequest", function (zEvent) {
//var xxxx = JSON.parse (zEvent.detail);
console.log ("Extension replied: ", zEvent.detail);
} );
$("body").prepend ('<button id="gmFileDownloadBtn">Click to File download request.</button>');
$("#gmFileDownloadBtn").click ( function () {
if (extensionLoaded) {
detailVal = JSON.stringify (
{targFileURL: fileURL, targSavePath: savePath}
);
var zEvent = new CustomEvent (
"SuicidalDownloadRequestToAddOn",
{"detail": detailVal }
);
window.dispatchEvent (zEvent);
}
else {
alert ("The file download extension is not loaded!");
}
} );
You can test the script on this SO question page.
Note that any other extension, userscript, web page, or plugin can listen to or send spoof events, the only security, so far, is to limit which pages the extension runs on.
For reference, the extension source files are below. The rest is supplied by Firefox's Add-on SDK.
The content script:
var zEvent = new CustomEvent ("ImAlivefromExtension",
{"detail": "GM, DANGER, DANGER, DANGER, File download utility" }
);
window.dispatchEvent (zEvent)
window.addEventListener ("SuicidalDownloadRequestToAddOn", function (zEvent) {
console.log ("Extension received download request: ", zEvent.detail);
//-- Relay request to extension main.js
self.port.emit ("SuicidalDownloadRequestRelayed", zEvent.detail);
//-- Reply back to GM, or whoever is pretending to be GM.
var zEvent = new CustomEvent ("ReplyToDownloadRequest",
{"detail": "Your funeral!" }
);
window.dispatchEvent (zEvent)
} );
The background JS:
//--- For security, MAKE THESE AS RESTRICTIVE AS POSSIBLE!
const includePattern = [
'https://mail.google.com/mail/*',
'https://stackoverflow.com/questions/14440362/*'
];
let {Cc, Cu, Ci} = require ("chrome");
Cu.import ("resource://gre/modules/Services.jsm");
Cu.import ("resource://gre/modules/XPCOMUtils.jsm");
Cu.import ("resource://gre/modules/FileUtils.jsm");
let data = require ("sdk/self").data;
let pageMod = require ('sdk/page-mod');
let dlManageWindow = Cc['#mozilla.org/download-manager-ui;1'].getService (Ci.nsIDownloadManagerUI);
let fileURL = "";
let savePath = "";
let activeWindow = Services.wm.getMostRecentWindow ("navigator:browser");
let mod = pageMod.PageMod ( {
include: includePattern,
contentScriptWhen: 'end',
contentScriptFile: [ data.url ('ContentScript.js') ],
onAttach: function (worker) {
console.log ('DANGER download utility attached to: ' + worker.tab.url);
worker.port.on ('SuicidalDownloadRequestRelayed', function (message) {
var detailVal = JSON.parse (message);
fileURL = detailVal.targFileURL;
savePath = detailVal.targSavePath;
console.log ("Received request to \ndownload: ", fileURL, "\nto:", savePath);
downloadFile (fileURL, savePath);
} );
}
} );
function downloadFile (fileURL, savePath) {
dlManageWindow.show (activeWindow, 1);
try {
let newFile;
let fileURIToDownload = Services.io.newURI (fileURL, null, null);
let persistWin = Cc['#mozilla.org/embedding/browser/nsWebBrowserPersist;1']
.createInstance (Ci.nsIWebBrowserPersist);
let fileName = fileURIToDownload.path.slice (fileURIToDownload.path.lastIndexOf ('/') + 1);
let fileObj = new FileUtils.File (savePath);
fileObj.append (fileName);
if (fileObj.exists ()) {
console.error ('*** Error! File "' + fileName + '" already exists!');
}
else {
let newFile = Services.io.newFileURI (fileObj);
let newDownload = Services.downloads.addDownload (
0, fileURIToDownload, newFile, fileName, null, null, null, persistWin, false
);
persistWin.progressListener = newDownload;
persistWin.savePrivacyAwareURI (fileURIToDownload, null, null, null, "", newFile, false);
}
} catch (exception) {
console.error ("Error saving the file! ", exception);
dump (exception);
}
}
So far from what you are saying,the only thing you can do is making add-on(Firefox) and Extension(for chrome if you want).
If you have closer look at download of attachment,it happens when:
1) You click on icon of attachments
2) If you click download
For these two things you can find the click event of <a> tag containing download_url value.You can easily do that using js/jquery for creting extension.
So you can write the functionality when user tries to download attachment.
You could use Gmail contextual gadgets to modify the behavior on the Google side:
Gmail Contexual Gadgets
Contextual Gadgets don't have direct access to attachments but server side, you could use IMAP to access the attachment (based on the Gmail message ID identified by the gadget):
Gmail IMAP Extensions
Using gadgets and server-side IMAP has the advantage of being browser-agnostic.
It's not entirely clear what you want to do differently with the downloaded Gmail attachment as opposed to any given download (save it to a different location? Perform actions upon the attachment data?) But the contextual gadget and IMAP should give you some chance to modify the attachment data as needed before the browser download begins.

Saving/Organizing/Searching Outlook E-mail outside of Outlook

My company requires me to use Outlook for my E-mail. Outlook does virtually nothing the way I want to do it and it frustrates me greatly. (I'm not trying to start a flame war here, it must do exactly what thousands of CEO's want it to do, but I'm not a CEO.)
I would like to be able to automatically extract the thousands of E-mails and attachments currently in my Outlook account and save them in my own alternative storage format where I can easily search them and organize them the way I want. (I'm not requesting suggestions for the new format.)
Maybe some nice open source program already can do this... that would be great. Please let me know.
Otherwise, how can I obtain the message content and the attachments without going through the huge collection manually? Even if I could only get the message content and the names of the attachments, that would be sufficient. Is there documentation of the Outlook mail storage format? Is there a way to query Outlook for the data?
Maybe there is an alternative approach I haven't considered?
My preferred language to do this is C#, but I can use others if needed.
Outlook Redemption is the best thing currently to use that I have found. It will allow you to get into the messages and extract the attachments and the message bodies. i am using it now to do just that.
Here is some code I use in a class. I included the constructor and the processing function I use to save off the attachments. I cut out the code that is specific to my needs but you can get an idea of what to use here.
private RDOSession _MailSession = new RDOSession();
private RDOFolder _IncommingInbox;
private RDOFolder _ArchiveFolder;
private string _SaveAttachmentPath;
public MailBox(string Logon_Profile, string IncommingMailPath,
string ArchiveMailPath, string SaveAttPath)
{
_MailSession.Logon(Logon_Profile, null, null, true, null, null);
_IncommingInbox = _MailSession.GetFolderFromPath(IncommingMailPath);
_ArchiveFolder = _MailSession.GetFolderFromPath(ArchiveMailPath);
_SaveAttachmentPath = SaveAttPath;
}
public void ProcessMail()
{
foreach (RDOMail msg in _IncommingInbox.Items)
{
foreach (RDOAttachment attachment in msg.Attachments)
{
attachment.SaveAsFile(_SaveAttachmentPath + attachment.FileName);
}
}
if (msg.Body != null)
{
ProcessBody(msg.Body);
}
}
}
edit:
This is how I call it and what is passed
MailBox pwaMail = new MailBox("Self Email User", #"\\Mailbox - Someone\Inbox",
#"\\EMail - Incomming\Backup", #"\\SomePath");
If you want to extract your e-mails take a look at
Outlook Email Extractor
at codeproject
http://69.10.233.10/KB/dotnet/OutlookEmailExtractor.aspx
rob
www.filefriendly.com

Resources