I have to develop a Google Action with a mandatory Account Linking phase that I have configured with an OAuth2 server. I'm using the online console at https://console.actions.google.com/ to develop the action.
I have set up the Start scene where the condition is user.validationStatus != "VERIFIED" . Based on the result of the condition I will go to 2 different scenes.
Here the screen of the Start scene where is checked the account linking status.
Here the Start_AccountLinking scene
But when I try to go in the "Test" section of the console after I open the action with the invocation, It doesn't pass any of the conditions and stays in the Start scene. In the log on the right, I can see that it failed both the conditions.
{
"conditionsEvaluated": {
"failedConditions": [
{
"expression": "user.validationStatus != \"VERIFIED\"",
"nextSceneId": "Start_AccountLinking"
},
{
"expression": "user.validationStauts == \"VERIFIED\"",
"nextSceneId": "AuthenticatedScene"
}
]
},
"responses": [
{
"firstSimple": {
"speech": "Benvenuto in Semiperdo",
"text": "Benvenuto in Semiperdo"
}
}
]
}
Instead of user.validationStatus use user.accountLinkingStatus. It will work!
Related
I am trying to redirect the user to the installed app when visiting www.example.com/success as well as show a banner when visiting the homepage www.example.com.
With my current implantation the url DOES NOT redirect and open the app and neither does the website display a banner.
I am following the documentation found here https://developer.apple.com/documentation/safariservices/supporting_associated_domains
My website is a simple create-react-app with a homepage hosted with Firebase.
I have done the following:
Add Associated Domains to Signing and Capabilities - applinks:website.com/success
Add apple-app-site-association file to /public/
Amend firebase.json file
Link to files in index.html
What I am using to validate:
https://branch.io/resources/aasa-validator/
https://search.developer.apple.com/appsearch-validation-tool
Testing by adding www.example.com/success link to notes and opening, It always opens in safari. I Have also tried reinstalling the app and restarting the phone.
Apple API Validation
I have uploaded a new app version with associated domains to the store
Branch.io
{
"applinks": {
"apps": [],
"details": []
}
}
When visiting www.example.com/apple-app-site-association
{ "activitycontinuation": { "apps": [ "team.com.example.com" ] },
"applinks": { "apps": [], "details": [ { "appID":
"team.com.example.com", "paths": [ "/", "/", "/success", "/success/",] }, "webcredentials": { "apps": [
"team.com.example.com" ] } }
apple-app-site-association
{
"activitycontinuation": {
"apps": [
"team.com.example.com"
]
},
"applinks": {
"apps": [],
"details": [
{
"appID": "team.com.example.com",
"paths": [
"/",
"/*",
"/success",
"/success/*",
]
},
]
},
"webcredentials": {
"apps": [
"team.com.example.com"
]
}
}
Index.html
<link rel="apple-app-site-association file" href="%PUBLIC_URL%/apple-app-site-association">
<link rel="apple-app-site-association file" href="/apple-app-site-association">
<meta name="App" content="app-id=XXX, app-argument=https://apps.apple.com/US/app/APP/idXXX, affiliate- data=optionalAffiliateData">
Firebase.json
{
"hosting": {
"public": "public",
"headers": [
{
"source": "/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
],
"appAssociation": "NONE"
}
}
Device Console
When installing the app I monitor the device console in Xcode looking through swdc process logs for anything related to associated domains or requests. Here's some I found;
Error getting enterprise-managed associated domains data. If this
device is not enterprise-managed, this is normal: Error
Domain=SWCErrorDomain Code=1701 "Failed to get associated domain data
from ManagedConfiguration framework."
UserInfo={NSDebugDescription=Failed to get associated domain data from
ManagedConfiguration framework., Line=298, Function=}
Entry { s = applinks, a = , d = au….ub….com, ua = unspecified,
sa = approved } needs its JSON updated because the app PI changed
https://developer.apple.com/library/archive/qa/qa1916/_index.html
First at your device logs and your JSON format it seems your should be following the example shown here: https://developer.apple.com/documentation/safariservices/supporting_associated_domains
In your logs it may shows logs from other apps who also have the outdated API format. However this should not be so much of an issue.
{
"applinks": {
"details": [
{
"appIDs": [ "ABCDE12345.com.example.app", "ABCDE12345.com.example.app2" ],
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": "Matches any URL whose fragment equals no_universal_links and instructs the system not to open it as a universal link"
},
{
"/": "/buy/*",
"comment": "Matches any URL whose path starts with /buy/"
},
{
"/": "/help/website/*",
"exclude": true,
"comment": "Matches any URL whose path starts with /help/website/ and instructs the system not to open it as a universal link"
},
{
"/": "/help/*",
"?": { "articleNumber": "????" },
"comment": "Matches any URL whose path starts with /help/ and which has a query item with name 'articleNumber' and a value of exactly 4 characters"
}
]
}
]
},
"webcredentials": {
"apps": [ "ABCDE12345.com.example.app" ]
},
"appclips": {
"apps": ["ABCED12345.com.example.MyApp.Clip"]
}
}
Secondly following the steps in Apple's troubleshooting and your problem I am guessing your problem might be Step 7
Your app returned false from one of the following
UIApplicationDelegate protocol methods:
application(:continueUserActivity:restorationHandler:),
application(:willFinishLaunchingWithOptions:),
application(_:didFInishLaunchingWithOptions:).
This can happen if you
parsed the URL that is passed into these methods, and you implemented
logic to determine that your app can not use this URL.
You have not posted how you handle the URL. You need to implement the UIUserActivityRestoring method as suggested in the other answer for it to work. Here is a SwiftUI version
ContentView()
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
print("Continue activity \(userActivity)")
guard let url = userActivity.webpageURL else {
return
}
print("User wants to open URL: \(url)")
// TODO same handling as done in onOpenURL()
}
Also add
.onOpenURL { url in
print("URL OPENED")
print(url) // parse the url to get someAction to determine what the app needs do
if url.relativeString == "example://success" {
}
}
https://developer.apple.com/library/archive/qa/qa1916/_index.html
There needs to be an appID in the apple-app-site-association:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "XXXXXXXXXX.com.example.UniveralLinks",
"paths": ["*"]
}
]
}
}
The applinks tag determines which apps are associated with the web site. Leave the apps value as an empty array. Inside the details tag is an array of dictionaries for linking appIDs and URL paths. For simplicity, you use the * wildcard character to associate all of this web site’s links with the UniversalLinks app. You can limit the paths value to specific folders or file names.
The appID consists of your team ID combined with the app’s bundle ID, but you’ll need to use the identifier for your own account.
Apple assigned you a team ID when you created your Apple developer account. You can find it in the Apple developer center. Log into the web site, click on Membership, then look for Team ID in the Membership Information section.
Now you have the apple-app-site-association it must be uploaded to the web server.
You must have “write access” to the web site to do this. Be sure you set up the apple-app-site-association file correctly (either at the root or in .well-known/ on your web server, and no redirects).
You'll also have to add the appropriate entitlements for universal linking to the iOS app.
If you're using Xcode:
Select the project.
Select the target.
Select the Capabilities tab.
Scroll to and turn ON Associated Domains.
Then you can add e.g. applinks:www.mywebsite.in under `Capabilities -> Associated Domains.
Or in your entitlements file, you can add something like the following:
<key>com.apple.developer.associated-domains</key>
<array>
...
<string>applinks:www.mywebsite.in</string>
...
</array>
Handling Universal Links:
Now that the app and the web site are officially aware of each other, all the app needs is code to handle the link when it’s called.
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?
) -> Void) -> Bool {
// 1
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
return false
}
// 2 // dig out component for deepLinking reference.
if let component = ItemHandler.sharedInstance.items
.filter({ $0.path == components.path}).first {
//handle navigation to page indicated by component
return true
}
// 3
if let webpageUrl = URL(string: "http://universal-links-final.example.com") {
application.open(webpageUrl)
return false
}
return false
}
iOS calls this method whenever the user taps a universal link related to the app. Here’s what each step does:
First, you verify that the passed-in userActivity has expected characteristics. Ultimately, you want to get the path component for the activity. Otherwise, you return false to indicate that the app can’t handle the activity.
Using the path, you look for a known view controller that matches it. If you find one, you present the view controller for it and return true.
If you can’t find a view controller that matches the path, you instruct the application to open the URL, which will use the default system app instead — most likely Safari. You also return false here to indicate that the app can’t handle this user activity.
I've set up my workflows and taskqueues.
Workflow looks like this.
{
"task_routing": {
"filters": [
{
"filter_friendly_name": "Dialpad",
"expression": "flexOutboundDialerTargetWorker != null",
"targets": [
{
"expression": "task.flexOutboundDialerTargetWorker == worker.contact_uri",
"queue": "WQ044385bd3c00a98cc63c092d02e5b571",
"timeout": 10
}
]
}
],
"default_filter": {
"queue": "WQ044385bd3c00a98cc63c092d02e5b571"
}
}
}
Task queue and workers are configured so that WQ044385bd3c00a98cc63c092d02e5b571 has available workers.
However, when I call the number, a task gets created, a reservation is made, but in the case that nobody os available, the task moves to the default_filterand it stays there forever.
What I want to do?
Remove the default_filter or set a timeout on it (can't really figure out how to edit the default filter)
Handle the canceled task myself using Event Callbacks
Turns out there's a visual option I missed located at:
https://www.twilio.com/console/taskrouter/workspaces/WSXXX/workflows
Scroll to bottom and set the DEFAULT QUEUE to None.
I create a shape on Gslide within text {{company_logo}}, but when I execute the request i get this message :
Invalid requests[0].replaceAllShapesWithImage: The operation is not allowed on notes page element
{
"requests":
[
{
"replaceAllShapesWithImage":
{
"imageUrl": "https://image.freepik.com/icones-gratuites/logo-de-pomme_318-40184.jpg",
"containsText":
{
"text": "{{company_logo}}"
}
}
}
]
}
Thanks,
Google Slides API team member here -- This was a bug on our side that was fixed on 12/20. Apologies for the breakage.
Link to this issue on our issue tracker: https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4991
I'm looking to set up smart commits in JIRA, but my developers want to know all the options for their transitions. In order to help them, I'd like to print a cheat-sheet of all transition names (I trust they are smart enough to figure out what does what from there).
But when I look through the REST API documentation, I can only find a way to get the list of transitions for a particular issue (presumably via its status). Is there a way to get the list of all transitions that any ticket can take at any point in its workflow?
You can list the transitions of a given ticket via this endpoint:
/rest/api/2/issue/${issueIdOrKey}/transitions
For a more in depth explanation take a look here:
Does the JIRA REST API require submitting a transition ID when transitioning an issue?
You can get all transitions for project with /rest/api/2/project/{projectIdOrKey}/statuses endpoint. Here is response example, look at "statuses" array:
[
{
"self": "http://localhost:8090/jira/rest/api/2.0/issueType/3",
"id": "3",
"name": "Task",
"subtask": false,
"statuses": [
{
"self": "http://localhost:8090/jira/rest/api/2.0/status/10000",
"description": "The issue is currently being worked on.",
"iconUrl": "http://localhost:8090/jira/images/icons/progress.gif",
"name": "In Progress",
"id": "10000"
},
{
"self": "http://localhost:8090/jira/rest/api/2.0/status/5",
"description": "The issue is closed.",
"iconUrl": "http://localhost:8090/jira/images/icons/closed.gif",
"name": "Closed",
"id": "5"
}
]
}
]
But it doesn't give you exactly list of transitions that any issue can take at any time, and I'm not sure that such method exist in API.
public void changeStatus(IssueRestClient iRestClient,
List<Statuses> JiraStatuses, String key) {
String status = "To Do";
for (Statuses statuses : vOneToJiraStatuses) {
if (1 == statuses.compareTo(status)) {
try {
String _transition = statuses.getTransition();
Issue issue = iRestClient.getIssue(key).get();
Transition transition = getTransition(iRestClient, issue,
_transition);
if (!(isBlankOrNull(transition))) {
if (!(issue.getStatus().getName()
.equalsIgnoreCase(_transition)))
transition(transition, issue, null, iRestClient,
status);
}
} catch (Exception e) {
Constants.ERROR.info(Level.INFO, e);
}
break;
}
}
}
List is a pojo implementation where statuses and transitions defined in xml are injected through setter/constructor.
private void transition(Transition transition, Issue issue,
FieldInput fieldInput, IssueRestClient issueRestClient,
String status) throws Exception {
if (isBlankOrNull(fieldInput)) {
TransitionInput transitionInput = new TransitionInput(
transition.getId());
issueRestClient.transition(issue, transitionInput).claim();
Constants.REPORT.info("Status Updated for : " + issue.getKey());
} else {
TransitionInput transitionInput = new TransitionInput(
transition.getId());
issueRestClient.transition(issue, transitionInput).claim();
Constants.REPORT.info("Status Updated for : " + issue.getKey());
}
}
public Transition getTransition(IssueRestClient issueRestClient,
Issue issue, String _transition) {
Promise<Iterable<Transition>> ptransitions = issueRestClient
.getTransitions(issue);
Iterable<Transition> transitions = ptransitions.claim();
for (Transition transition : transitions) {
if (transition.getName().equalsIgnoreCase(_transition)) {
return transition;
}
}
return null;
}
In Short using Transition API of JIRA we can fetch all the transitions to set statuses
When a page is called, I want to check the call on depending on the path, I want to redirect the user to the frontpage, with some parameters. These parameters I will use in a block to show extra information to the visitor.
What hook should I use, so that drupal has to do the least unnecessary work ?
1) The template_preprocess_page function is the appropriate hook here.
2) An alternative option is to use Rules module.
Event: Drupal is initializing (using hook_init)
Condition: Execute custom php code (check path argument)
Actions: Page redirect, Other rules actions (eg a Message)
I would suggest to show a Drupal Message to the user instead of a block. Except if user is logged in and parameters shown in block do exist in the database so you can use views module to create that block.
Here is an export of a rule that redirects if the taxonomy term page display belongs to Vocabulary '4'. Import it to your rules to see the results.
{ "rules_taxonomy_redirect_business" : {
"LABEL" : "Taxonomy redirect - Business",
"PLUGIN" : "reaction rule",
"TAGS" : [ "redirect", "taxonomy" ],
"REQUIRES" : [ "php", "rules" ],
"ON" : [ "init" ],
"IF" : [
{ "php_eval" : { "code" : "$check1 = (arg(0)==\u0027taxonomy\u0027)\u0026\u0026(arg(1)==\u0027term\u0027);\r\n$check2 = (arg(3)!=\u0027edit\u0027);\r\n\r\nif (arg(2)) {\r\n$tid = arg(2);\r\n$vid = db_query(\u0027SELECT vid FROM {taxonomy_term_data} WHERE tid = :tid\u0027, array(\u0027:tid\u0027 =\u003E $tid))-\u003EfetchField();\r\n$check3 = ($vid == \u00274\u0027);\r\n}\r\n\r\nreturn ($check1)\u0026\u0026($check2)\u0026\u0026($check3);" } }
],
"DO" : [
{ "redirect" : { "url" : "\u003C?php\r\n$tid = arg(2);\r\nreturn \u0027business?cat%5B%5D=\u0027 . $tid;\r\n?\u003E" } }
]
}
}