How to implement caching in MS Teams Client SPFX Webpart - caching

I am trying to implement caching for a SPFX WebPart using #pnp-Storage. The caching is working alright in the Temas browser but in the Teams client, it isn't working. It is very slow as I have to make multiple azure function call. Can someone please help me with caching in the Team's app. Please refer the code below.
// Getting data from session variable
This.isListsExists = this.storage.session.get(isListsExists);
// If it exists in the session variable then don't make the HTTP call. Otherwise, make the
// call and save it in the session variable.
if (!this.isListsExists) {
this.isListsExists = await this.mapDataProvider.checkIfAllListsExist(); //cache
// Setting Session variable.
this.storage.session.put(isListsExists, this.isListsExists, end);
}

I was using session storage and it wasn't working with teams but when I changed it to local storage it worked like a charm.
// Edit - Cache code
this.isListsExists = this.storage.local.get(isListsExistsCache);
// console.log("isListsExists - " + this.isListsExists);
if (!this.isListsExists) {
this.isListsExists = await this.mapDataProvider.checkIfAllListsExist(); //cache
this.storage.local.put(isListsExistsCache, this.isListsExists, end);
}

Related

How to get query sys_id of current.sys_id Service Portal (ServiceNow)

I have a question regarding a small issue that I'm having. I've created a widget that will live on the Service Portal to allow an admin to Accept or Reject requests.
The data for the widget is pulling from the Approvals (approval_approver) table. Under my GlideRecord, I have a query that checks for the state as requested. (Ex. addQuery('state', 'requested'))
To narrow down the search, I tried entering addQuery('sys_id', current.sys_id). When I use this query, my script breaks and I get an error on the Service Portal end.
Here's a sample of the GlideRecord script I've written to Accept.
[//Accept Request
if(input && input.action=="acceptApproval") {
var inRec1 = new GlideRecord('sysapproval_approver');
inRec1.addQuery('state', 'requested');
//inRec1.get('sys_id', current.sys_id);
inRec1.query();
if(inRec1.next()) {
inRec1.setValue('state', 'Approved');
inRec1.setValue('approver', gs.getUserID());
gs.addInfoMessage("Accept Approval Processed");
inRec1.update();
}
}][1]
I've research the web, tried using $sp.getParameter() as a work-around and no change.
I would really appreciate any help or insight on what I can do different to get script to work and filter the right records.
If I understand your question correctly, you are asking how to get the sysId of the sysapproval_approver record from the client-side in a widget.
Unless you have defined current elsewhere in your server script, current is undefined. Secondly, $sp.getParameter() is used to retrieve URL parameters. So unless you've included the sysId as a URL parameter, that will not get you what you are looking for.
One pattern that I've used is to pass an object to the client after the initial query that gets the list of requests.
When you're ready to send input to the server from the client, you can add relevant information to the input object. See the simplified example below. For the sake of brevity, the code below does not include error handling.
// Client-side function
approveRequest = function(sysId) {
$scope.server.get({
action: "requestApproval",
sysId: sysId
})
.then(function(response) {
console.log("Request approved");
});
};
// Server-side
var requestGr = new GlideRecord();
requestGr.addQuery("SOME_QUERY");
requestGr.query(); // Retrieve initial list of requests to display in the template
data.requests = []; // Add array of requests to data object to be passed to the client via the controller
while(requestsGr.next()) {
data.requests.push({
"number": requestsGr.getValue("number");
"state" : requestsGr.getValue("state");
"sysId" : requestsGr.getValue("sys_id");
});
}
if(input && input.action=="acceptApproval") {
var sysapprovalGr = new GlideRecord('sysapproval_approver');
if(sysapprovalGr.get(input.sysId)) {
sysapprovalGr.setValue('state', 'Approved');
sysapprovalGr.setValue('approver', gs.getUserID());
sysapprovalGr.update();
gs.addInfoMessage("Accept Approval Processed");
}
...

CMS Open Payments Data Limitation

I've finally got around to getting the code needed to import web API into my SQL environment. However, when I ran the SSIS Script Component package (Script Language: Visual Studio C# 2017) I was only able to retrieve 1000 records out of of millions. A consultant mentioned that I may have to incorporate the App Token into my code in order to access additional records.
Would someone be able to confirm that this true? And if so, how should it be coded?
Here is the code prior to my "ForEach" loop code:
public override void CreateNewOutputRows()
{
//Set Webservice URL
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
string wUrl = "https://openpaymentsdata.cms.gov/resource/bqf5-h6wd.json";
string appt = "MyAppToken";
try
{
//Call getWebServiceResult to return our Article attributes
List<Payment> outPutResponse = GetWebServiceResult(wUrl);
If there's an alternative method to using the app token (like in the HTTP Connection for example) please let me know.
Figured it out...
https://openpaymentsdata.cms.gov/resource/bqf5-h6wd.json?$limit=10000&$$app_token="MyAppToken"

How to extract state parameter from OpenIdConnect Token response in .Net Core MVC

We are using Azure b2c to handle our logins on our .net core MVC site.
We would like to use the optional state parameter to hold onto some data/a value between the initial request to the site (this value would likely be in a querystring param) which is then sent off to b2c to login, and the successfully logged in return back to the site.
OpenIDConnect allow the setting of this state value in the request, and will pass it back with the token response.
It appears that setting the value is relatively simple; in the OnRedirectToIdentityProvider event in the OpenIdConnectOptions like so:
public Task OnRedirectToIdentityProvider(RedirectContext context){
...
context.ProtocolMessage.SetParameter("state", "mystatevalue");
...
}
however, I cannot see how to get this value back again when the user is returned.
I can see that the OnTicketReceived event is hit, and this has a TicketReceivedContext which has a Form property with a state value in it, however this is still encrypted.
Where would i be able to get the un-encrypted value back from?
I have had a look at the Azure docs for b2c but I cannot find an example on this.
thanks
Managed to get this working by using the OnTokenValidated event.
This is able to get the unencrypted parameter as below.
...//first set up the new event
options.Events = new OpenIdConnectEvents()
{
...
OnTokenValidated = OnTokenValidated
};
...
private Task OnTokenValidated(TokenValidatedContext tokenValidatedContext)
{
var stateValue = tokenValidatedContext.ProtocolMessage.GetParameter("state");
if (stateValue != null)
{
//do something with that value..
}
return Task.CompletedTask;
}

Telegram Bot Random Images (How to send random images with Telegram-Bot)

const TeleBot = require('telebot');
const bot = new TeleBot({
token: 'i9NhrhCQGq7rxaA' // Telegram Bot API token.
});
bot.on(/^([Hh]ey|[Hh]oi|[Hh]a*i)$/, function (msg) {
return bot.sendMessage(msg.from.id, "Hello Commander");
});
var Historiepics = ['Schoolfotos/grr.jpg', 'Schoolfotos/boe.jpg',
'Schoolfotos/tobinsexy.jpg'];
console.log('Historiepics')
console.log(Math.floor(Math.random() * Historiepics.length));
var foto = Historiepics[(Math.floor(Math.random() * Historiepics.length))];
bot.on(/aap/, (msg) => {
return bot.sendPhoto(msg.from.id, foto);
});
bot.start();
The result I'm getting from this is just one picture everytime, but if I ask for another random picture it keeps showing me the same one without change.
I recently figured this out, so I'll drop an answer for anyone that runs into this issue.
The problem is with Telegram's cache. They cache images server side so that they don't have to do multiple requests to the same url. This protects them from potentially getting blacklisted for too many requests, and makes things snappier.
Unfortunately if you're using an API like The Cat API this means you will be sending the same image over and over again. The simplest solution is just to somehow make the link a little different every time. This is most easily accomplished by including the current epoch time as a part of the url.
For your example with javascript this can be accomplished with the following modifications
bot.on(/aap/, (msg) => {
let epoch = (new Date).getTime();
return bot.sendPhoto(msg.from.id, foto + "?time=" + epoch);
});
Or something similar. The main point is, as long as the URL is different you won't receive a cached result. The other option is to download the file and then send it locally. This is what Telebot does if you pass the serverDownload option into sendPhoto.

SysCache2 and FluentNhibernate on MVC aplication

I am having a problem with SysCache/SysCache2 on my MVC application. My configuration seems to be correct. I have set it up just like countless examples on the web.
On my class I have put: Cache.Region("LongTerm").NonStrictReadWrite().IncludeAll();
Here is a Test I made for the application cache.
[Test]
public void cache()
{
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
var acc = session.QueryOver<Log>().Cacheable().List();
tx.Commit();
}
var test = sessionFactory.Statistics.SecondLevelCacheHitCount;
using (var session = sessionFactory.OpenSession())
{
var acc = session.QueryOver<Log>().List();
}
var test1 = sessionFactory.Statistics.SecondLevelCacheHitCount;
}
The first statement is cached as I see in the session factory statistics (for example 230 records).
If i understand it right second statement that is below shouldnt hit the db but the Cache.
Problem here is that it goes to DB anyway. Checked with profiler to be 100% sure.
I don't know what am I doing wrong here. Anyone has an idea?
I have managed to solve this problem. It had to do with my session creation. I didn't use session per request which triggered not going to cache. I created transaction on begining and it lasted through entire session. I managed to trigger entering cache if i opened the session again within using mark like: using(var sess = session.SessionFactory.OpenSession()) but this solution was only a workaround which didn't suit me so I changed how I created sessions in the first place and it works fine now! :)

Resources