Is there any way to keep the session open after alexa timer api goes off? - api

I would like to know if there are any possible ways or tricks where we can leave the session open for the user's input after the timer goes off because the timer API doc doesn't cover it.
timer_request_1 = {
"duration": "PT15S",
"timerLabel": "Change name",
"creationBehavior": {
"displayExperience": {
"visibility": "VISIBLE"
}
},
"triggeringBehavior": {
"operation": {
"type": "ANNOUNCE",
"textToAnnounce": [
{
"locale": "en-US",
"text": "Would you like to proceed with the x task?"
}
]
},
"notificationConfig": {
"playAudible": False
}
}
}
REQUIRED_PERMISSIONS = ["alexa::alerts:timers:skill:readwrite"]
class TimerIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
return ask_utils.is_intent_name("TimerIntent")(handler_input)
def handle(self, handler_input):
permissions = handler_input.request_envelope.context.system.user.permissions
if not (permissions and permissions.consent_token):
return (
handler_input.response_builder
.speak("Please give permissions to set timers using the alexa app.")
.set_card(
AskForPermissionsConsentCard(permissions=REQUIRED_PERMISSIONS)
)
.response
)
timer_service = handler_input.service_client_factory.get_timer_management_service()
timer_response = timer_service.create_timer(timer_request)
if str(timer_response.status) == "Status.ON":
session_attr = handler_input.attributes_manager.session_attributes
if not session_attr:
session_attr['lastTimerId'] = timer_response.id
speech_text = 'Your 40 minutes timer has started!.'
return (
handler_input.response_builder
.speak(speech_text)
.response
.ask("Would you like to proceed x task?")
)
else:
speech_text = 'Timer did not start'
return (
handler_input.response_builder
.speak(speech_text)
.response
)
I tried by adding a return .ask() but I got 'Response' object has no attribute 'ask' error.
Looking forward to hearing your thoughts :)

You use response to get the response from response_builder so you should place all speak, ask etc. builder methods before response.

One way to keep the session alive is to not send "shouldEndSession". This will not let the session close. But this will not be approved if you go for certification.

Related

rightnow-crm and unavailable hours

we have recently implemented rightnow proactive chat on our website, we have the chat widget set up by our central IT department to work off hours of availability for chat. I've got the widget working to an OK standard using this example
http://cxdeveloper.com/article/proactive-chat-intercepting-chat-events
However, coming from Zendesk I was hoping to replicate the 'out of hours' or 'offline' modes of the Zendesk widget where it changes its behaviour when chat is offline.
After looking around I notice the widget can take a value for 'label_unavailable_hours:' however I cannot work out if this is available to the both the ConditionalChatLink and ProactiveChat modules. Does anyone have any experience with creating such functionality? I've also had a look at trying to pull data using chatAvailability but I am not doing that right either.
If anyone has an insight on how to get some kind of out of hours smarts working or if I am wasting my time try Id love to hear. My code is as below
$(document).ready(function() {
RightNow.Client.Controller.addComponent({
instance_id: "spac_0",
avatar_image: "",
label_question: "A team member is available to help, would you like to start a chat?",
label_avatar_image: "",
label_dialog_header: "",
logo_image: "",
seconds: 2,
enable_polling: "yes",
div_id: "proactiveChatDiv",
module: "ProactiveChat",
//module: "ConditionalChatLink",
min_agents_avail: 0, //remove this when live (when set to 0, no agents have to be free)
min_sessions_avail: 1,
label_unavailable_busy_template: "'All team members are busy. please email is us' + <a href='urlForEmail'>' + 'this place' + '</a>'", //out of hours
label_unavailable_hours: "'Outside of hours' + <a href='urlForEmail'>' + 'this place' + '</a>'",
type: 2
},
"https://ourWidgetCode"
);
//Widget loaded callback - this doesn't seem to work correctly hence the code below
RightNow.Client.Event.evt_widgetLoaded.subscribe(function(event_name, data) {
if (data[0].id == "spac_0") {
//Initialization
console.log('widget loaded');
}
/* this wont work
spac_0.prototype.chatAvailability = spac_0.chatAvailability;
spac_0.chatAvailability = function()
{
console.log(spac_0.chatAvailability);
{}
};*/
//Reset prototype
spac_0.prototype = {};
//Handle Chat Offered
spac_0.prototype.chatOffered = spac_0.chatOffered;
spac_0.chatOffered = function() {
console.log("Chat Offered Handled");
spac_0.prototype.chatOffered.call(this);
//animate the widget to popup from bottom
setTimeout(function() {
$('div.yui-panel-container').addClass('animate');
}, 2000)
//delete the annoying session cookie that only allows the chat to appear once per session by default
RightNow.Client.Util.setCookie("noChat", '', -10, '/', '', '');
};
//if the 'Do not ask again' is selected
spac_0.prototype.chatRefused = spac_0.chatRefused;
spac_0.chatRefused = function () {
console.log("Do not ask again Selected");
spac_0.prototype.chatRefused.call(this);
//Reset the Cookie to be valid only for the session
RightNow.Client.Util.setCookie("noChat",'RNTLIVE',0,'/',true,'');
};
});
});

Karate - how to access an array element by UUID during a 'retry until' statement

I have an endpoint which returns this JSON response:
{
"jobs": [
{
"name": "job1",
"id": "d6bd9aa1-0708-436a-81fd-cf22d5042689",
"status": "pending"
},
{
"name": "job2",
"id": "4fdaf09f-51de-4246-88fd-08d4daef6c3e",
"status": "pending"
}
]
I would like to repeatedly GET call this endpoint until the job I care about ("job2") has a "status" of "completed", but I'd like to check this by using a UUID stored in a variable from a previous call.
i.e. by doing something like this:
#NB: code for previous API call is executed
* def uuidVar = response.jobRef
#NB: uuidVar equates to '4fdaf09f-51de-4246-88fd-08d4daef6c3e' for this scenario
* configure retry = { count: 5, interval: 10000 }
Given path /blah
And retry until response.jobs[?(#.id==uuidVar)].status == 'completed'
When method GET
Could anyone suggest the correct syntax for the retry until?
I've tried referencing the fantastic Karate docs & examples (in particular, js-arrays.feature) and some questions on SO (including this one: Karate framework retry until not working as expected) but sadly I haven't been able to get this working.
I also tried using karate.match here as suggested in the link above, but no cigar.
Apologies in advance if I am missing something obvious.
First I recommend you read this answer on Stack Overflow, it is linked from the readme actually, and is intended to be the definitive reference. Let me know if it needs to be improved: https://stackoverflow.com/a/55823180/143475
Short answer, you can't use JsonPath in the retry until expression, it has to be pure JavaScript.
While you can use karate.jsonPath() to bridge the worlds of JsonPath and JS, JsonPath can get very hard to write and comprehend. Which is why I recommend using karate.filter() to do the same thing, but break down the steps into simple, readable chunks. Here is what you can try in a fresh Scenario:. Hint, this is a good way to troubleshoot your code without making any "real" requests.
* def getStatus = function(id){ var temp = karate.filter(response.jobs, function(x){ return x.id == id }); return temp[0].status }
* def response =
"""
{
"jobs": [
{
"name": "job1",
"id": "d6bd9aa1-0708-436a-81fd-cf22d5042689",
"status": "pending"
},
{
"name": "job2",
"id": "4fdaf09f-51de-4246-88fd-08d4daef6c3e",
"status": "pending"
}
]
}
"""
* def selected = '4fdaf09f-51de-4246-88fd-08d4daef6c3e'
* print getStatus(selected)
So if you have getStatus defined up-front, you can do this:
* retry until getStatus(selected) == 'completed'
Note you can use multiple lines for a JS function if you don't like squeezing it all into one line, or even read it from a file.

Make Scrapy send POST data from Javascript function

I'm playing with Scrapy and playing with this tutorial. Things look good but I noticed Steam changed their age check so there is no longer a form in DOM. So the suggested solution will not work:
form = response.css('#agegate_box form')
action = form.xpath('#action').extract_first()
name = form.xpath('input/#name').extract_first()
value = form.xpath('input/#value').extract_first()
formdata = {
name: value,
'ageDay': '1',
'ageMonth': '1',
'ageYear': '1955'
}
yield FormRequest(
url=action,
method='POST',
formdata=formdata,
callback=self.parse_product
)
Checking an example game that forces age check; I noticed the View Page button is no longer a form:
<a class="btnv6_blue_hoverfade btn_medium" href="#" onclick="ViewProductPage()"><span>View Page</span></a>
And the function being called will eventually call this one:
function CheckAgeGateSubmit( callbackFunc )
{
if ( $J('#ageYear').val() == 2019 )
{
ShowAlertDialog( '', 'Please enter a valid date' );
return false;
}
$J.post(
'https://store.steampowered.com/agecheckset/' + "app" + '/9200/',
{
sessionid: g_sessionID,
ageDay: $J('#ageDay').val(),
ageMonth: $J('#ageMonth').val(),
ageYear: $J('#ageYear').val()
}
).done( function( response ) {
switch ( response.success )
{
case 1:
callbackFunc();
break;
case 24:
top.location.reload();
break;
case 15:
case 2:
ShowAlertDialog( 'Error', 'There was a problem verifying your age. Please try again later.' );
break;
}
} );
}
So basically this is making a POST with some data...what would be the best way to do this in Scrapy, since this is not a form any longer? I'm just thinking on ignoring the code where the form is obtained and simply send the request with the FormRequest object...but is this the way to go? An alternative could also be setting cookies for age and pass it on every single request so possibly the age check is ignored altogether?
Thanks!
You should probably just set an appropriate cookie and you'll be let right through!
If you take a look at what your browser has when entering the page:
and replicate that in scrapy:
cookies = {
'wants_mature_content':'1',
'birthtime':'189302401',
'lastagecheckage': '1-January-1976',
}
url = 'https://store.steampowered.com/app/9200/RAGE/'
Request(url, cookies)
lastagecheckage should probably be enough on it's own but I haven't tested it.

Getting all bids from each Header bidding partners

We are implementing some header bidding partners on our wrapper using prebid. Is it possible to get all bids from each ssp.
Any help appreciated.
If you’re asking about demand, this is dependent on each SSP. For example there may be a segment pixel or placement in one SSP that will always give you a $10 bid, but that wouldnt apply to the other SSPs.
If your asking about getting data on all the bids, you may want to check out pbjs.getBidResponses() which returns an object with the ad units and bids
Heres a sample response from pbjs.getBidResponses() which can then be used however you'd need that data:
{
"div-id-one": {
"bids": [
{
"bidderCode": "appnexus",
"width": 970,
"height": 250,
"statusMessage": "Bid available",
"adId": "1293a95bb3e9615",
"mediaType": "banner",
"creative_id": 77765220,
"cpm": 0.7826,
"adUrl": "https://...",
"requestId": "57f961f3-a32b-45df-a180-9d5e53fb9070",
"responseTimestamp": 1513707536256,
"requestTimestamp": 1513707535321,
"bidder": "appnexus",
"adUnitCode": "div-id-one",
"timeToRespond": 935,
"pbLg": "0.50",
"pbMg": "0.70",
"pbHg": "0.78",
"pbAg": "0.75",
"pbDg": "0.78",
"pbCg": "0.78",
"size": "970x250",
"adserverTargeting": {
"hb_bidder": "appnexus",
"hb_adid": "1293a95bb3e9615",
"hb_pb": "0.78",
"hb_size": "970x250"
}
}
]
},
"div-id-two": {
"bids": []
}
}
Theres also a great example on prebid.org on how to output this to console.table that could be helpful as well:
var responses = pbjs.getBidResponses();
var output = [];
for (var adunit in responses) {
if (responses.hasOwnProperty(adunit)) {
var bids = responses[adunit].bids;
for (var i = 0; i < bids.length; i++) {
var b = bids[i];
output.push({
'adunit': adunit, 'adId': b.adId, 'bidder': b.bidder,
'time': b.timeToRespond, 'cpm': b.cpm, 'msg': b.statusMessage
});
}
}
}
if (output.length) {
if (console.table) {
console.table(output);
} else {
for (var j = 0; j < output.length; j++) {
console.log(output[j]);
}
}
} else {
console.warn('NO prebid responses');
}
There is also a chrome extensions called Prebid helper that do the same as console snippet but with less clicks.
However that is useful for initial setup debug. If you need to gather aggregated data on all demand partners - bids, timeouts, wins etc. You will need to run third party wrapper analytics or use analytics adapter. It's not free but it usually is priced depending on your load on the analytics server. For example https://headbidder.net/pricing
Try out the Chrome Extension called Adwizard. It's been built to debug prebid setups. Shows you all networks and bids per adunit. CPM and Size included.
https://chrome.google.com/webstore/detail/adwizard/kndnhcfdajkaickocacghchhpieogbjh/?ref=stackoverflow

Google Sheets API addProtectedRange Error: No grid with id: 0

I am not sure if I am making a mistake or if possibly this is related to the same issue reported here:
Google Sheets API V4 - Autofill Error - No grid with id: 0
I am getting:
HttpError 400
"Invalid requests[0].addProtectedRange: No grid with id: 1"
Code is something like this (additional addProtectedRange objects removed)
def add_protected_ranges(spreadsheet_id):
service = get_sheets_service()
requests = [
{
"addProtectedRange": {
'protectedRange': {
"range": {
"sheetId": 1,
"startRowIndex": 0,
"endRowIndex": 0,
"startColumnIndex": 0
},
"description": "Headers must not be changed",
"warningOnly": True
}
}
}
]
body = {
'requests': requests
}
response = service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_id,
body=body).execute()
Had kind of the same issue. I was confusing the sheet id with sheet index.
Easiest way to find the sheet id is in the browser URL when you open the spreadsheet / sheet: https://docs.google.com/spreadsheets/d/{spreadsheetId}/edit#gid={sheetId}
If you're looking for a more programmatic way you find that property on the SheetProperties.
I know that's an old question but I was looking for it too. You're looking for:
res.data.sheets[].properties.sheetId
To get the sheetId (not the spreadsheetId) use:
sheets.spreadsheets.get({
spreadsheetId
}).then(res => {
console.log("All the sheets:");
for(i in res.data.sheets) {
let title = res.data.sheets[i].properties.title;
let id = res.data.sheets[i].properties.sheetId;
console.log(title + ': ' + id);
}
});
Make sure that there is a workbook with the id 1 in your spreadsheet. In google sheet, a spreadsheet can contain multiple worksheet(grid), there is a unique id for each of the worksheet(grid).