I'm accessing a URI from my controller which at the moment is hardcoded to my current SAP Cloud Platform Sub-Account.
window.open("https://rsaactionplan-(subaccount).dispatcher.hana.ondemand.com/index.html#/actionplan/" + oBindingContext.JobId, "_system");
Rather than hard-code it, how can I access the current sub-account ID so I can dynamically setup the sub-account in the SAPUI5 controller?
You can get access to account related details using Tenant Context APIs.
Please check here for details https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/a8f2255658ba4cbfb3ec3ab0f928f360.html?q=TenantContext
Best Regards,
Saurav
My solution for both hybrid + web app.
following any oData Read......
var uriStr;
if (typeof sap.hybrid !== 'undefined') {
uriStr = oUserData.__metadata.uri;
}
else{
uriStr = window.location.href;
}
var split1 = uriStr.split("-"); // split by -
var secondSubString = split1[1]; // all characters AFTER the first -
var split2 = secondSubString.split("."); // split by .
self.subAccount = split2[0]; // all characters BEFORE the first .
Then use self.subAccount into the calling URI.
Related
Our company has multiple brands and each brand has its own host name, but they are all part of the same site. We can let customers share baskets and other session information when they switch between brands via a redirect link using URLUtils.sessionRedirect.
But URLUtils is not available in content assets. Is it possible to form a session redirect link in content asset keeping all the session information?
Thanks in advance.
You can include dynamic content in Content Assets with the $include('Controller-Name', 'name1', 'value1', 'name2', 'value2', ...)$ syntax. See the MarkupText Class Documentation for more info on that syntax. The 'name1' and 'value1' parameters are mapped as query string attributes eg: Controller-Name?name1=value1&name2=value2
Create a controller that outputs the session redirect link you need, and call it via that syntax like: $include(Util-RenderSessionLink, 'siteID', 'foo')$
The controller would need to use a response Content-Type header of text/plain or something like that so that nothing is injected into the response. (eg: Storefront toolkit or tracking tags) For example:
response.setContentType('text/plain');
Alternatively, you could process the content asset for some sorts of keys that you perform find & replace operations on. For example, the following code does a find & replace on a Content Asset's body content for the key: '%%SessionLink%%'.
var ContentMgr = require('dw/content/ContentMgr');
var URLUtils = require('dw/web/URLUtils');
if (!empty(content) {
var content = ContentMgr.getContent('my-content-id');
var contentOut = "";
var viewData = {};
contentOut = content.custom.body.getMarkup()
.replace('%%SessionLink%%', URLUtils.sessionRedirect(...));
viewData.content = contentOut;
// then output your `pdict.content` key within a template with the appropriate encoding
}
If anybody else is running into this, we added a bit of client-side javascript that pickups up all outbound links and if it's one of our domains it sends them through a session redirect. This way we don't need content managers to fix very link between domains:
var domains = ["domaina.com", "domainb.com", "domainc.com"]
var sessionRedirectBase = '/s/Our-Site/dw/shared_session_redirect';
$(document).on("click.crossSite", "a", (e) => {
const href = $(e.currentTarget).attr("href");
if (href) { //does the link have a href
if (href.match(/^(http(s)?:)?\/\//)) { //is href an absolute url
const url = new URL(href);
if (url.hostname != window.location.hostname && domains.indexOf(url.hostname) > -1) { //is hostname not the current one and part of the domains array
e.preventDefault();
const sessionRedirect = `${sessionRedirectBase}?url=${encodeURIComponent(href)}`
window.location = sessionRedirect;
}
}
}
});
Within our Google Apps Org, I would like to setup a shared contact list that anyone inside our company can access and add/edit the contacts so we have all the same information. What is the best way to go about this?
I would create an application in App Engine that uses the Google APIs to edit the Shared Contacts list. That way you can restrict access to your domain users and also audit the activity that is occurring. There are third party tools out there that can edit the shared contact list but this is typically locked down to avoid situations where users delete contacts they should not be able to. Don't forget that the Shared Contacts list that appears in Gmail's type-ahead has a 24 hour delay.
Hey for anyone out there we used a Google Sheet, now anyone can update the sheet and you can either set an automated trigger to upload them on a schedule or manually push them into the Google Directory.
gsheet:
First we pull all the contacts from the directory then you can add/update/delete existing or new contacts.
Then push them to the Directory using the menu.
We made setup super simple so it auto grabs the user info and domain etc without the user having to do anything
var SHEET_NAME = 'google';
var ERROR_RECIPIENT_MAIL= Session.getActiveUser().getEmail();
var DOMAIN = ERROR_RECIPIENT_MAIL.replace(/.*#/, "");
Then we call the Domain Shared Contacts API to get all the data and put it into an array:
function getAllContacts(){
var contacts = ContactsApp.getContacts();
var lastRow = SpreadsheetApp.getActiveSpreadsheet().
getSheetByName(SHEET_NAME).getLastRow();
if (lastRow >2) SpreadsheetApp.getActiveSpreadsheet().
getSheetByName(SHEET_NAME).deleteRows(3, lastRow*1-2);
var contacts = ContactsApp.getContacts();
var params = {
method : "get",
contentType : "application/atom+xml",
headers : {"Authorization": "Bearer " +
ScriptApp.getOAuthToken(),"GData-Version": "3.0"},
muteHttpExceptions : true
};
var startIndex=1;
var data,respCode,resp;
resp = UrlFetchApp.fetch("//www.google.com/m8/feeds/contacts/"
+DOMAIN+"/full?alt=json&start-index="+startIndex, params);
respCode=resp.getResponseCode();
//SpreadsheetApp.getActiveSpreadsheet().
// getSheetByName(SHEET_NAME).getRange("A10").setValue(resp);
data = JSON.parse(resp.getContentText());
From there it's then put in the correct fields on the sheet for the user to update. Then the user selects the action from the drop down which calls the appropriate function when the script is run to update.
Example of delete function:
function deleteContact(contactID,rowNumber){
var params = {
method : "delete",
contentType : "application/json",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken(),"GData-Version": "3.0","If-Match":"*"}
};
var resp = UrlFetchApp.fetch(contactID, params);
var respCode=resp.getResponseCode();
if (respCode=='201' || respCode=='200') {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME).deleteRow(rowNumber*1);
}
else{
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME).getRange(rowNumber*1, 15, 1, 1).setValue('ERROR');
ERROR_COUNT=ERROR_COUNT.toString()+rowNumber;
}
}
It's pretty cool, and now we are working on bulk data entry as it seems to stall or stop after about 700 contacts in a single run. Also some of the contacts don't get synced and have an error which we'll work on shortly to get the user more info and even store the missed contact to be fixed and updated after. Anyway hope that helps and gives you some ideas.
Ours is located here for anyone interested.
I'm building an App with ASP.NET MVC 5 and Identity.
So far the login is working correctly.
Here the auth:
var fb = new FacebookAuthenticationOptions();
fb.Scope.Add("email");
fb.Scope.Add("friends_about_me");
fb.Scope.Add("friends_photos");
fb.AppId = "";
fb.AppSecret = "";
fb.Provider = new FacebookAuthenticationProvider() {
OnAuthenticated = async FbContext => {
FbContext.Identity.AddClaim(
new System.Security.Claims.Claim("FacebookAccessToken", FbContext.AccessToken));
}
};
fb.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
app.UseFacebookAuthentication(fb);
I'm trying to get the friends list. I've been looking for a few examples but none is working with this version of MVC 5.
My question is. How can I fetch all the friends with this version?
I don't want to use Javascript API, I want all the code in c# and then send to the view.
I think I just need to rewrite the login and store the access token in the session, and then simply call var client = new FacebookClient(TOKEN);
So how can I rewrite the login?
You've already got everything you need. The OnAuthenticated callback you've set adds a claim containing the access token for Facebook. You just need to pull the claim for the user:
var identity = (ClaimsIdentity)User.Identity;
var facebookClaim = identity.Claims.FirstOrDefault(c => c.Type == "FacebookAccessToken");
if (facebookClaim != null)
{
// access facebook API with `facebookClaim.Value`
}
And if it exists, then you can use the Facebook API to pull in their friends by making standard HTTP calls via something like HttpClient.
I am trying to access a local SharePoint site using a .net program and am having difficulties.
I don't want to use the SharePoint development environment (may have many developers work on this, and that is just one more thing to install).
I would also like to make this configurable so that I can change the site and list name without recompiling. I don't think I can do that with the Service References. If I can, how?
I also don't want the user to enter sharepoint validation information, I am ok with storing sharepoint login information in a .config file.
I believe I could do this with REST, but can't figure out how to create an AccessToken without using the Sharepoint development environment.
Any help would be appreciated.
The main problem I was having was not understanding that you could put other types of credentials in the request.Credentials property. Here is the code I created:
public bool CopyFileToSharePoint(string fileName, Stream fileStream)
{
var data = new byte[fileStream.Length];
fileStream.Read(data, 0, (int) fileStream.Length);
fileStream.Close();
var sharePointPath =
SharePointWebSiteUrl + "/_api/web/lists/getByTitle('" + SharePointListName + "')" +
"/RootFolder/Files/add(url='" + fileName + "',overwrite='true')";
var request = (HttpWebRequest) WebRequest.Create(sharePointPath);
request.Credentials = new NetworkCredential(SharePointUserName, SharePointPassword, SharePointLoginDomain);
request.Method = "POST";
request.Accept = "application/atom+xml";
request.Headers["X-RequestDigest"] = GetFormDigest(SharePointWebSiteUrl);
request.ContentType = "application/txt";
request.ContentLength = data.Length;
request.GetRequestStream().Write(data, 0, data.Length);
var response = (HttpWebResponse) request.GetResponse();
return response.StatusCode == HttpStatusCode.OK;
}
I'm sure it's not perfect, but it works.
is there a way I can make events on the standard Facebook events app appear on a custom Google Map I've created?
Any tips would be much appreciated.
Given you have the user_events permission, you can access the locations like so:
FB.api("/me/events", function(events) {
if(events.error)
console.error(events);
var map = "http://maps.googleapis.com/maps/api/staticmap?zoom=14&size=512x512&maptype=roadmap&sensor=false";
for(var i = 0; i < events.data.length; i++) {
var point = "&markers=color:blue%7Clabel:S%7C";
point += (events.data[i].venue.latitude + "," + events.data[i].venue.longitude);
map += point;
}
var img = document.createElement("IMG");
img.src = map;
document.body.appendChild(img);
});
I didn't test it, but this should be enough to show an example of how to access the API in the browser and render a map with it's information. This is using Google Maps static API.
I just created a python script, source here.
It queries the given facebook page and it's events and puts the data into a MySQL table. It also contains a Geo-cache library, which combines a local database with the Google Maps Geocoding API, so you can query the longitude and the latitude of the events very fast.