Logging errors to the ULS with JSOM - javascript

For SharePoint 2013, is there any way to log to the ULS using the JSOM?
If possible I would like to avoid doing things like writing a custom handler that can be called with ajax.

SharePoint provides a web service named SharePoint Diagnostics (diagnostics.asmx), this web service enables a client application to submit diagnostic reports directly to the ULS logs, follow Writing to the SharePoint Unified Logging Service from JavaScript for a more details.
SharePoint JavaScript library (init.js) contains the following functions that consume Diagnostics web service:
function ULSOnError(msg, url, line) {
return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller);
}
function ULSSendException(ex) {
var message = ex.message;
if (typeof message == "undefined")
message = ex.toString();
ULSSendExceptionImpl(message, location.href, 0, ULSSendException.caller);
}
Example
var ctx = SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(listTitle);
ctx.load(list);
ctx.executeQueryAsync(function() {
//...
},
function(sender,args){
ULS.enable = true; //ensure ULS logging is enabled
ULSOnError('An error occured while getting list' + args.get_message(), location.href, 0);
});

Related

Outlook AddIn GetAsync successful but returns nothing

I've got an Outlook Add In that was developed using the Office Javascript API.
It looks at the new email being composed & does things based on who it's going to: https://learn.microsoft.com/en-us/office/dev/add-ins/reference/objectmodel/requirement-set-1.3/office.context.mailbox.item
The code correctly returns the TO email when you 'select' the email from the suggested email list... screenshots shown # bottom of this thread
To debug the Javascript, I use C:\Windows\SysWOW64\F12\IEChooser.exe
It was working fine until last week. Is it possible a Windows update broke functionality?
I'm the only person with access to the code. It hadn't been modified for months.
When debugger is running, getAsync correctly returns the 'TO' value. I needed to write the response to a global variable to prove the values were 'undefined' while not in debug.
var resultObjects;
var resultObjects2;
var strMessages = '';
var strTo = '';
var mailbox;
var mailitem;
(function () {
"use strict";
// The Office initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
mailbox = Office.context.mailbox;
mailitem = mailbox.item;
mailitem.to.getAsync(function (result) {
if (result.status === 'failed') {
strMessages = 'FAILED';
} else {
strMessages = 'SUCCESS';
strTo = result.value[0];
resultObjects = result;
resultObjects2 = result.value;
}
});
loadApp();
});
};
})();
Here are the values of the variables, when the app is loaded & debugger is not running
EDIT
If you 'select' the TO email so that it is bolded... the code works correctly. If you leave the typed-in-text field without selecting the suggested email, it does not work. The same behavior is true for both the Outlook Web Application (# https://outlook.office.com) and the desktop outlook application.
Does not work
Does Work
The Office.context.mailbox.item.to.getAsync API will only return resolved recipients. If the TO email address is not resolved (as in the first screenshot titled "Does not Work"), then API will not return the email address until it is resolved (in both desktop and OWA).
You can use the RecipientsChanged Event, to get newly resolved recipients after you have queried for to.getAsync. This event would fire when a recipient is newly resolved.

Facebook OG Meta with Angular and Node

I am trying to get my angular / node application to render dynamic Open graph meta content.
I have been trying to follow this tutorial http://www.codewarmer.com/posts/1394433236-configuring-angularjs-nodejs-for-search-bots#!
I am having some problems with phantom working with node, my issue seems to be similar to this Error message when using PhantomJS, breaks at random intervals
except that my error does not happen at random intervals, it happens all the time.
EDIT: Here is my code
In my server.js I require a module i created based on the above tut called PhantomHandler.js and it is called like so.
var crawler = require('./modules/PhantomHandler');
This is what PhantomHandler.js looks like:
var phantom = require('phantom');
var models = require('../models');
mongoose = require('mongoose');
Snapshot = models.Snapshot;
url = require('url');
var baseUrl = 'my url';
function crawlSite(idx, arr, page, callback) {
crawlUrl(arr[idx], page, function(data) {
data.links.forEach(function(link) {
if (arr.indexOf(link) < 0)
arr.push(link);
});
Snapshot.upsert(data);
if (++idx === arr.length)
callback();
else
crawlSite(idx, arr, page, callback);
});
}
function startPhantom(cb) {
phantom.create(function(ph) {
phInstance = ph;
ph.createPage(function(page) {
phPage = page;
cb(ph, page);
});
});
}
function crawlUrl(path, page, cb) {
uri = url.resolve(baseUrl, path);
page.open(uri, function(status) {
var evaluateCb = function(result) {
result.path = path;
cb(result);
};
//Timeout 2000ms seems pretty enough for majority ajax apps
setTimeout(function() {
if (status == 'success')
page.evaluate(function() {
var linkTags = document.querySelectorAll('a:not([rel="nofollow"])');
var links = [];
for (var i = 0, ln; ln = linkTags[i]; i++)
links.push(ln.getAttribute('href'));
return {
'links': links,
'html': document.documentElement.outerHTML
};
}, evaluateCb);
}, 2000);
});
}
exports.crawlAll = function(callback) {
startPhantom(function(ph, page) {
crawlSite(0, ['/'], page, function() {
ph.exit();
callback();
});
});
};
exports.crawlOne = function(path, callback) {
startPhantom(function(ph, page) {
crawlUrl(path, page, function(data) {
Snapshot.upsert(data);
ph.exit();
callback();
});
});
};
When i run this code my exact error is:
phantom stderr: 'phantomjs' is not recognized as an internal or exte
,
operable program or batch file.
assert.js:92
throw new assert.AssertionError({
^
AssertionError: abnormal phantomjs exit code: 1
at Console.assert (console.js:102:23)
at ChildProcess.<anonymous> (path to node modules\node_modules\phantom\phantom.js:150:28)
at ChildProcess.emit (events.js:98:17)
at Process.ChildProcess._handle.onexit (child_process.js:809:12)
My question: Is this the best easiest way to go about getting angular to play nicely with Facebook OG? If it is can anyone else confirm if they have managed to get this technique to work with out phantom throwing an assertion error as described above.
It seems like this should be a relatively common job and I am surprised that I haven't found a nice straight forward tutorial on how to get this to work, unless i just haven't looked properly :s
Thanks
Okay,
Because my question was essentially "What is the best way to get angular and node to respond to Facebook with the correct page meta". I am now in a position to post my answer to this.
As stated above I think that using the phantom.js method described above requires phantom to be installed and to run as a separate process on the node.js server. (Can anyone confirm or deny this?)
For my situation I just wanted a user to be able to post a link from the site onto Facebook and for Facebook to return a nice looking link using open graph meta.
With that in mind I decided to skip the phantom.js step from the solution in the tutorial above. Instead I rolled some code which essentially saves an HTML snippet into the DB when a user hits a page. The HTML snippet just contains the meta tags I need for Facebook. I then use the last part of the above tutorial to direct Facebook bots to my saved HTML snippet.
It seems to work pretty well.

Get data from API in Google Apps Script, how to?

im trying to access the calendar resources data in the Google Apps domain.
I have this:
function myFunction() {
var url = 'https://apps-apis.google.com/a/feeds/calendar/resource/2.0/example.com/';
var response = UrlFetchApp.fetch(url);
Logger.log(response);
}
But i need to authorize.
"Request failed for https://apps-apis.google.com/a/feeds/calendar/resource/2.0/example.com/ returned code 401. Authorization required "
Does someone know how i Authorize? I tried to add the advances services and Calendar API, but didn't work.
Why don't you use Calendar Service in Google Apps Script. It allows you to interact with Calendar Objects and Events without worrying for oAuth.
e.g to Fetch Events in Calendar
function fetchEVents() {
var d1 = new Date("4/26/2013");
var d2 = new Date("4/26/2014");
var events = CalendarApp.openByName("myCalendarName").getEvents(d1, d2);
if (events.length > 0) { // Log the time of first event
Logger.log(events[0].getStartTime() + " : " + events[0].getEndTime());
}
}
For more details, you may refer to the following resources.
https://developers.google.com/apps-script/reference/calendar/
https://developers.google.com/apps-script/articles/sites_tutorial#section2

How to Create Gmail Filters Programmatically?

I would like to create Gmail filters programmatically in a Chrome extension for standard Gmail users (read non Google App). Currently, thanks to those 2 (outdated) resources:
Grexit Filters API
Gmail Filter Assistant, Userscript
I have managed to develop an early prototype able to create a filter which automatically archives ("cf2_ar=true") emails received at a certain email address ("cf1_to="). However, it seems like any other "cf2" parameters used by Gmail are not valid anymore. For instance, applying a label with parameters "cf2_cat=" or "cf2_sel=" does nothing.
I know that Gmail's code is not very friendly and open when it comes to app or extension development but I would appreciate any help if some of you have any ideas, suggestions or updates regarding the current parameters used by Gmail to create filters, especially the one(s) used to apply labels to messages.
script.js (DOM end)
// Inject API into Gmail DOM
var s = document.createElement('script');
s.src = chrome.runtime.getURL('js/lib/api.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
s.parentNode.removeChild(s);
};
document.addEventListener('Demo_connectExtension', function(e) {
if(e.detail) {
// Gmail GLOBALS : DATA
DATA = e.detail;
user_data[0] = DATA[9]; // Id (ik)
user_data[1] = DATA[10]; // Email
user_data[2] = DATA[17][9][8]; // Locale
user_data[3] = DATA[7]; // Gmail inbox
var emailarr = user_data[1].split('#');
user_data[4] = emailarr[0] + '+do#' + emailarr[1]; // email for filter
var regex_cookie = new RegExp("GMAIL_AT=(.+?);");
if (typeof document.cookie !== 'undefined') {
// Get cookie
var gmcookie = document.cookie.match(regex_cookie)[1];
console.log('cookie:' + gmcookie);
var gmail_filter_url = 'https://mail.google.com' + user_data[3] +
'/?ui=2&ik=' + user_data[0] +
'&at=' + gmcookie +
'&view=up&act=cf&pcd=1&mb=0&rt=c';
var postdata = 'search=cf&cf1_to=' +
encodeURIComponent(user_data[4]) +
'&cf2_ar=true';
$.post(gmail_filter_url, postdata, function(gmail_response){
console.log(gmail_response);
});
}
// [...]
api.js (injected into Gmail)
'use strict';
var GLOBALS;
setTimeout(function() {
/* Send Gmail Data to my extension */
document.dispatchEvent(
new CustomEvent('Demo_connectExtension', {
detail: GLOBALS
}));
}, 1);
Actually, cf2_sel parameter does work for me. I had somewhat similar issue, described in this question and answer.
My code uses Grexit filters project and solves a sample use case:
"When a keyword is present in email content, add label, archive and set filter for this keyword"
I tested it successfully and when looking at Grexit code, 'labelas' action sets abovementioned "cf2_sel" parameter.
My sample project can be found here and provide you with means for quick testing and verification if this works for you.

How would I make a post on the users wall extending this example?

I am making an app with phonegap, adobe build and using facebook for authentication with this snippet of code.
I am looking to handle the 'success' login with some form of callback I suppose, and make a post on the user's wall.
<script type="text/javascript">
var my_client_id = "133914256793487", // YOUR APP ID
my_secret = "862f10f883f8d91617b77b4b143abc8d", // YOUR APP SECRET
my_redirect_uri = "https://www.facebook.com/connect/login_success.html", // LEAVE THIS
my_type ="user_agent", my_display = "touch"; // LEAVE THIS
var facebook_token = "fbToken"; // OUR TOKEN KEEPER
var ref; //IN APP BROWSER REFERENCE
// FACEBOOK
var Facebook = {
init:function(){
// Begin Authorization
alert("we have begun");
var authorize_url = "https://www.facebook.com/dialog/oauth?";
authorize_url += "client_id=" + my_client_id;
authorize_url += "&redirect_uri=" + my_redirect_uri;
authorize_url += "&display=" + my_display;
authorize_url += "&scope=publish_stream";
//CALL IN APP BROWSER WITH THE LINK
ref = window.open(authorize_url, '_blank', 'location=no');
ref.addEventListener('loadstart', function(event){
Facebook.facebookLocChanged(event.url);
});
} ,
facebookLocChanged:function(loc){
if (loc.indexOf("https://www.facebook.com/connect/login_success.html") >= 0 ) {
//CLOSE INAPPBROWSER AND NAVIGATE TO INDEX
ref.close();
//THIS IS MEANT TO BE DONE ON SERVER SIDE TO PROTECT CLIENT SECRET
var codeUrl = 'https://graph.facebook.com/oauth/access_token?client_id='+my_client_id+'&client_secret='+my_secret+'&redirect_uri='+my_redirect_uri+'&code='+loc.split("=")[1];
console.log('CODE_URL::' + codeUrl);
$.ajax({
url: codeUrl,
data: {},
type: 'POST',
async: false,
cache: false,
success: function(data, status){
//WE STORE THE TOKEN HERE
localStorage.setItem(facebook_token, data.split('=')[1].split('&')[0]);
},
error: function(){
alert("Unknown error Occured");
}
});
}
}
}
</script>
<script type="text/javascript">
Facebook.init();
</script>
Can anybody advise how to appropriately extend this example - and where I can find the API to be able to help myself? Currently it successfully asks the user to login - facebook pops up - I successfully accept and then it returns with Success - and a red message saying the user should retain this URL securely.
Cheers,
Andy
I know that changing the whole structure of your code is a bit of a daunting task, but I highly recommend using PhoneGap Facebook Plugin. And since you're using build, you can also easily integreate the Facebook Connect plugin from Build.
I highly recommend you check out the following two files found within the phonegap-facebook-plugin / example / HackBook folder of the PhoneGap Facebook plugin repository: index.html and js/auth.js .
When using the javascript FB Api, you can specify a callback function as the first parameter, as in FB.login(function(response) { ... }); You can find an example in the docs.
Line 25 of auth.js shows an example of making a call to the FB API, using the following code FB.api('/me' .... While this code requests information about the logged in user, you can make any javascript API call with FB.api(), which you can learn about here (look at the fourth example).
Check out the code and see how it works/how it's implemented, and let me know if you have any questions :)

Categories

Resources