How to schedule a notification with changing data expo - react-native

I am trying to make an app that utilizes expo's local notification feature and have run into an issue. I would like to make a notification that repeats every day at a certain interval with its data changing each day. I tried to use this syntax below, but it did not work as it only ran the function once, setting that value in stone for the rest of the notifications to come.
Expected (10 mins: "1", 20 mins: "2", 30 mins: "3" etc.)
Actual (10 mins: "1", 20 mins: "1", 30 mins: "1" etc.)
Notifications.scheduleNotificationAsync({
content: {
title: 'My Notification',
body: this.someFunctionThatReturnsANewValue()
},
trigger: {
minutes: 10,
repeats: true
}
});
In that case, I wanted to know if anyone had any idea on how to make a notification that uses the repeat property and has a body component that changes values each time it is triggered. The only other way I can think of giving a notification a different value as the last is scheduling 100+ notifications in advance, but that is not pretty nor practical. Any help or suggestions towards how I can accomplish this would be greatly appreciated, thanks!

In your component's useEffect or your application's App.js declare the Notifications.addNotificationReceivedListener event. It will be executed every time the application receives a new notification. Within the asynchronous function execute "await Notifications.cancelAllScheduledNotificationsAsync ();" to clear the scheduled notification and call Notifications.scheduleNotificationAsync again with the new message. The use of
repeats: true in this case is not necessary. Doing this, every time the application receives a notification it clears the one that existed before and programs a new one with a different message

Related

GoogleFit on iphone: problem with REST API calls

I'm trying to query, with the Fit rest API, segmented data from an iphone that have installed GoogleFit and configured the sync between apple health and googelfit.
To my android phone, I get the data as expected with this POST:
(*)
"aggregateBy": [
{
"dataSourceId": "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps",
"dataTypeName": "com.google.step_count.delta"
},
{
"dataSourceId": "derived:com.google.distance.delta:com.google.android.gms:merge_distance_delta",
"dataTypeName": "com.google.distance.delta"
}
{
"dataSourceId": "derived:com.google.active_minutes:com.google.android.gms:merge_active_minutes",
"dataTypeName": "com.google.active_minutes"
}
],
"endTimeMillis": 1643325227000,
"startTimeMillis": 1640991600000,
"bucketByActivitySegment": {
"minDurationMillis": 600000
}
}
But from the iphone user, this returns an empty bucket.
I checked the available data dataSources for the apple user. I did some "trial and error" on the dataSourceIds connected to "active_minutes". In particular
derived:com.google.active_minutes:com.google.ios.fit:appleinc.:iphone:1148c16f:top_level
derived:com.google.active_minutes:com.google.ios.fit:appleinc.:watch:f40f5c4a:top_level
The trial and error werer conducted with aggregateBy post with one of the above sources, so no distance and step_count involved. The two above dataSourceIds were obtained from a "list post query" for available dataSources, done by the iphone user, with the following scopes:
fitness.activity.read
fitness.location.read
No segmented data is returned from either dataSourceIds (an empty bucket as well).
Contents within the apple user's app indicates that there should be segmented data somewhere, see screenshot link.
(Edit: also tried setting "minDurationMillis: 0")
Meanwhile, queries such as:
(**)
{
"aggregateBy": [
{
"dataSourceId": "derived:com.google.distance.delta:com.google.android.gms:merge_distance_delta",
"dataTypeName": "com.google.distance.delta"
}
],
"endTimeMillis": 1643325227000,
"startTimeMillis": 1640991600000,
"bucketByTime": {
"durationMillis": 2333627000
}
}
does return data from the apple user. But I'm really interested in segments (minimum 10 minutes long)
So, question: Anyone with experience getting segmented data from apple-googlefit users?
Figure:
iphone screenshot
Update.
Since (**) (see first post) did return data from the iphones, I went with a 1-hour "bucketByTime"-solution for both androids and iphones.
If segments is important, it is possible to parse/filter the "bucketByTime" data into segments. However, activity type is not obtained with this POST.
New problem(s) have arisen:
As mentioned, (**) POST returned data. Particularly when:
"startTimeMillis" = [start of 2022]
and
"endTimeMillis" = [now].
A cron executor is configured such that (**) is repeated once a day where:
"startTimeMillis" = ["previous now"]
and
"endTimeMillis" = [now].
However, this does not return any data from the iphone users. To clarify, no daily data is received from the iphones.
Some preformed check-ups:
The iphone users see data as normal on the front-end view of the GoogleFit app (see screenshot link in first post).
Attempted (**) with every "dataStreamId" and "name" available (returned from "list post query" for available dataSources) - Nothing is returned.
Asked the iphone users to check GoogleFit's permissions, in accordance with this support page. (I'll have to take their word that it's configured correctly)
Important finding:
For one iphone user, "incomplete"[2] data is occasionally returned. I'm imagining this data is data recorded by his apple watch. I asked him to wear his watch today.
You'd figure, when asking for eg. merge_distance_delta the app merges the available sources into a neat timeline. Questions on this level is not available publicly (to my knowledge).
[2] The sum does not (come close) to matching the GoogleFiT front-end results (as it does for the android users).

How to create local notification with an end date

I need to do local notification with an end date. I have taken look at https://wix.github.io/react-native-notifications/docs/localNotifications/ and https://github.com/zo0r/react-native-push-notification but cannot find an example of how it would work. I want a notification to have start and end date with an interval
This is answer is geared towards the second library you mentioned: https://github.com/zo0r/react-native-push-notification.
For setting the start date for when a notification should occur we have
the localNotificationSchedule method described in the documentation here: https://github.com/zo0r/react-native-push-notification#scheduled-notifications.
For example:
import PushNotification from 'react-native-push-notification';
PushNotification.localNotificationSchedule({
id: "1",
message: "My Notification Message", // (required)
date: new Date(Date.now() + 60 * 1000), // in 60 secs
// other props...
});
So whatever date object you pass to the date property will be the moment the notification is triggered.
Note that autoCancel by default has the value of true so after the notification is delivered the notification will be canceled anyway. So it's better not to handle the end date as it's already handled for you.
If you still want to cancel it anyway you can add autoCancel: true to the example above and cancel the notification like this:
PushNotification.cancelLocalNotifications({id: '1'});
So if you want to control the end date, an idea could be to first trigger your push notification and directly after call cancelLocalNotifications inside setTimeout. Then you could control when the notifications starts and when it is canceled.
If you want to have a way to do this in the background you can look into a background task library like https://github.com/transistorsoft/react-native-background-fetch.

How to create "Round Robin Call Forwarding Function" in Twilio Stack

I have researched high and low through multiple websites and have not found a single fully documented solution for round-robin call forwarding with-in the Twilio stack; let alone within Twilio Studio. The last time this question was asked in detail was in 2013 so your help is greatly appreciated. I am looking to find a solution to the following to educate myself and others:
[Round Robin Scenario]
Mentioned by Phil Krnjeu on Aug 1 '13 at 23:04, "I'm trying to create a website that has a phone number on it (say, a phone number for a school). When you call that number, it has different secretary offices (A,B,C, D). I want to create something where the main number is called, and then it goes and calls phone number A the first time, the second time someone calls the main number, number B is called, C, then D. Once D is called (which would be the 4th call), the 5th call goes back to A."
The response to the above question was to use an IVR Screening & Recording application which requires the caller to pick an agent which is not a true Round Robin solution. The solution I am looking for and many others require the system to know which agent is in a group and which agent is next to receive a call.
[Key Features Needed]
Ability to add forwarding numbers as identified above A, B, C, D as a group or IVR extensions such as 1 = Management, 2 = Sales and etc...
Set a subsequent calling rule that notates in a DB of some sort. Caller A through D, for example, equals 1 unsuccessful. When caller A has been forwarded a call it now equals 0 successful then the script stops and allows the call to be answered by the user or its voicemail. Then the next call comes in and is forwarded to user B and assigned a 0 successful value, then the script stops.
After the caller finishes the call or finishes leaving a voicemail the script needs to end the call.
[Final Destination]
The round-robin should finalize its call with the forwarded phone numbers voicemail.
[Known Issues]
Forwarding a call to multiple numbers not stopping when someone answers
[Options]
Once this question is posted I am sure someone will ask in the near future what if I wanted the call to be forwarded to a Twilio voicemail instead of using the forwarded phone number's voicemail which could be let's say a cell phone. I do not necessarily need this feature, however, making an additional comment would be very helpful to the community. Thank you for your time.
I have limited knowledge of programming besides having the ability to review articles posted by other users. One article I researched in detail that did not work for me was, "IVR: Screening & Recording with PHP and Laravel."
The solution I am looking for first would be to make this code through the new Twilio Studio interface if that is not possible then any other solution would be helpful to all.
Sam here from the Twilio Support Team. You can build what you've described using Twilio's Runtime suite, Studio, and Functions.
I wrote a blog post with detailed instructions and screenshots here, and I've included a summarized version below as well.
CREATE YOUR VARIABLE
First, you need to create a serverless Variable which will be used as the round robin counter. The variable must be inside an Environment, which is inside a Service. This is the only part of the application where you will need your own laptop. You can see how to create these with any of the SDKs or using curl in the docs.
Create a Service
Create an Environment
Create a Variable
Be sure to copy the SIDs of your Service, Environment, and Variable since you will need that for your function.
For convenience, this is how you create the Variable in NodeJS.
const accountSid = 'your_account_sid';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);
client.serverless.services('ZSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
.environments('ZEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
.variables
.create({key: 'key', value: 'value'})
.then(variable => console.log(variable.sid));
CREATE YOUR FUNCTION
Create the following Environment Variables here in the console and save set them equal to their respective SID that you saved earlier.
RR_SERVICE_SID
RR_ENV_SID
RR_VAR_SID_CTR
Next, make sure you check the Enable ACCOUNT_SID and AUTH_TOKEN checkbox above the Environment Variables section under Credentials.
Be sure your Twilio Client version in the Dependencies section is set to the latest, so we can be sure it includes the Serverless resources. At the time of writing (March 2020), the default Client version does not include them, so we upgraded to 3.41.1, which was the latest.
Go here in the console and create a blank Function.
Copy and paste the following code and replace the numbers with the ones you would like to include in your Round Robin (make sure the environment variables you just created match what's in the code).
exports.handler = function(context, event, callback) {
// Number List
let numbers = [
"+18652142345", //Sam
"+18651092837", //Tina
"+19193271892", //Matt
// Copy and paste line above to add another number.
];
// Initialize Twilio Client
let client = context.getTwilioClient();
// Fetch Round Robin Ctr
client.serverless.services(context.RR_SERVICE_SID)
.environments(context.RR_ENV_SID)
.variables(context.RR_VAR_SID_CTR)
.fetch()
.then(variable => {
// Use counter value to determine number to call
let number = numbers[variable.value];
// Create var with new ctr value
let ctr = variable.value;
// Check if current counter value is less than RR length (i.e. the number of numbers in round robin)
// If so, increment
if(ctr == numbers.length-1) {
ctr = 0;
}
// Otherwise reset ctr
else ctr++;
// Update counter value
client.serverless.services(context.RR_SERVICE_SID)
.environments(context.RR_ENV_SID)
.variables(context.RR_VAR_SID_CTR)
.update({value: ctr})
.then(resp => {
// Return number to call
let response = {number};
// Return our counter value and a null error value
callback(null, response);
});
});
};
CREATE YOUR STUDIO FLOW
Click the red plus sign to create a new Flow here.
Give the Flow a name and click Next.
Scroll to the bottom of the templates and click 'Import from JSON' and click Next.
Paste the Flow JSON shown here and click Next.
Click the RoundRobin function widget and select the Function you just created under the Default service.
Click the FunctionError widget, click MESSAGING & CHAT CONFIG, and change the SEND MESSAGE TO number to a number that you would like to notify by text in the event of a Function failure.
Click the DefaultNumber widget and change the default number that will be forwarded to in the event of a Function failure.
Click the Publish button at the top of your Flow.
CONFIGURE YOUR TWILIO NUMBER
Go here in the console.
Click the Twilio number you would like to configure.
Scroll down to the A CALL COMES IN dropdown in the Voice section and select Studio Flow.
Select your new Flow in the Select a Flow dropdown to the right.
Click Save at the bottom.
And that's it. You're now all set to test!

Get Jenkins Metrics data through API

What I need with the API call
I need the timeline info for each of the builds via the API call for Jenkins metrics plugin. I am using a web API to get data for my jobs in my jenkins. However, calling $JenkinsUrl/metrics/APIkey is leading me nowhere. Any idea how can I achieve the information?
All three bits of timeline info for each build (queue time, building time, total time) are available via the "get build" API.
On the screen where it shows "8.1 sec waiting in the queue" etc, click on the "REST API" link in the page footer, then "JSON API", then add &depth=2 to the end of the resulting API URL.
note, if you're searching for specific values in the API json, that the times will be in milliseconds. after you parse the json, build time is under the "duration" property, and the other two are in the array under the "actions" property. for me, it was the third element of the array, but that may vary (find the one with _class "jenkins.metrics.impl.TimeInQueueAction"):
{
"_class": "jenkins.metrics.impl.TimeInQueueAction",
"queuingDurationMillis": 16,
"totalDurationMillis": 4365
}
so in my example the build time was 4349 and the queue time was 16, so the total time was 4349 + 16 = 4365 milliseconds.
Instead of adding &depth=2 to the end of the url, you might be able to get exactly the three values you want by appending this to the url: &tree=duration,actions[queuingDurationMillis,totalDurationMillis]

Wit.ai seems to be jumping randomly between stories

I have two separate simple stories on my Wit.ai bot,
the first one takes in the word "Debug", sends "test" then runs a function that outputs context stuff to the console called test_context()
the second one takes in an address, runs a function that changes the context called new_session(), then sends a confirmation of the change to the user structured like "your location has been changed to {address}"
when I type directly into the wit.ai test console it seems to correctly detect the stories and run the corresponding functions, but when I try to use it through the Node.js API it seems to act completely randomly.
Sometimes when typing in an address it will run test_context() followed by new_session(), then output no text, sometimes it will just output the test text followed by the address text and run no functions, sometimes it will act correctly.
The same behavior happens when inputting "Debug" as well.
The back end is set up correctly, as 2 other stories seem to be working perfectly fine.
Both of these stories were working fine earlier today, I have made no changes to the wit stories themselves and no change to the back-end has even touched the debug function.
Is this a known issue?
I encountered this problem as well.
It appears to me as when you do not handle setting context variables in the story from wit.ai correctly (by setting them to null for example), it messes up the story. As a developer it is your own responsability to handle the story correctly "client side", so I can understand wit.ai lets weird stuff happen when you do not do this. Maybe wit.ai decided to jump stories to keep their bot from crashing, still remains a bit mysterious to me. Maybe your problem is of a different kind, just sharing a similair observation and my solution.
Exactly for reasons of testing I created three stories;
handle greetings
tell what the weather in city x is
identify when you want to plan a meeting
The bot is connected to facebook and I handle actions (like planning a meeting) on my nodejs express server.
I said to the bot "I want to plan a meeting tomorrow", resulting in a wit date/time. One timeslot by the way. This is going ok. Then I sent the message "I want to plan a meeting this morning". This resulted in TWO date/time variables in the wit.ai context. In turn, my code could not handle this; two timestamps resulted in null (probably json message getting more complicated and I try to get the wrong field). This in turn resulted in null for the context variable that had to be returned.
So what I did is to catch the error for when the context variable is not filled and just fill in [wit.js could not find date]. This fixed the problem, even though I now of course need to handle this error better.
Old code:
'createAppointment': ({sessionId, context, text, entities}) => {
return new Promise(function(resolve, reject) {
const myDateTime = firstEntityValue(entities, 'datetime');
console.log('the time trying to send ',myDateTime);
createAppointment(context, myDateTime)
context.appointmentText = myDateTime
return resolve(context);
},}
New, working code:
'createAppointment': ({sessionId, context, text, entities}) => {
return new Promise(function(resolve, reject) {
const myDateTime = firstEntityValue(entities, 'datetime');
console.log('the time trying to send ',myDateTime);
if(myDateTime){
createAppointment(context, myDateTime)
context.appointmentText = myDateTime
return resolve(context);
} else {
context.appointmentText = '[wit.js could not find date]'
return resolve(context);
}
});
},
Hope this helps