We are using Ionic 4 with lazy loading. My app routing works by app.routing.module.ts file. How to use deep link to open app from external link like email or sms?
It seems you didn't type this into Google first so this question is likely going to be closed shortly.
Ionic provide a deep linking library:
https://ionicframework.com/docs/native/deeplinks
It's used like this:
this.deeplinks.routeWithNavController(this.navController, {
'/about-us': AboutPage,
'/products/:productId': ProductPage
}).subscribe(match => {
// match.$route - the route we matched, which is the matched entry from the arguments to route()
// match.$args - the args passed in the link
// match.$link - the full link data
console.log('Successfully matched route', match);
}, nomatch => {
// nomatch.$link - the full link data
console.error('Got a deeplink that didn\'t match', nomatch);
});
You are supposed to do as much research as you can on your own before you open a question on StackOverflow. People are happy to help but they usually want to see you have tried for yourself as you are just giving your job to somebody else otherwise.
Related
I've been developing an app with firebase and stripe payment. I've created a checkout session in stripe and added firebase dynamic links for the success_url and cancel_url. The URLs are working fine. I've tested them outside stripe with a simple html file and it opens the app and takes the user to the correct page. If the page doesn't exist it'll take the user to the assigned website. This is stripe checkout session code:
const session = await stripe.checkout.sessions.create({
line_items: [{
price_data: { currency: 'INR', unit_amount: amount, product_data: { name: 'name' } },
quantity: 1,
}],
mode: 'payment',
success_url: 'https://-------.page.link/payment-success',
cancel_url: 'https://-------.page.link/payment-failed',
payment_intent_data: {
application_fee_amount: fee
},
}, {
stripeAccount: req.query.stripeId,
});
I've changed up the actual link since I don't know how much I'm allowed to share. But I can guarantee the dynamic links works fine. But after payment, the test payment at least, it's suppose to open the app and take the user to a payment success page. AND it was working fine for the first 2 or 3 days. After payment it re-opened the app and took the user to the correct page. But when I tried a few days later, this is what it's taking us to:
Again, I've removed the link since I don't know how much I'm allowed to share. It won't even open the app right now. It just shows this message in the browser. Both success and cancel url are doing the same. Why does the links work outside the function but not in it? Has anyone ever faced any similar issues before? Any help will be greatly appreciated.
It seems like you're trying to open the Checkout Session in a WebView which causing the issue in the redirect. Webviews don't know how to handle an URL Scheme other than http:// or https://. That being said, your problem isn't uncommon and there are multiple ways of solving this.
Your first approach would be to open the Checkout Session in an external browser as described in this answer or try to create your own WebViewClient and override shouldOverrideUrlLoading method like described in this answer. Just note that since the last edit of that answer the signature of the shouldOverrideUrlLoading method has changed but the logic should still be used the same way but instead of dealing with the String url, you will have to deal with a WebResourceRequest.
Had the same issue. I solved it by changing the mode like following:
await launchUrl(
url,
mode: LaunchMode.externalApplication, // Add this line
)
url_launcher version => 6.1.7
I'm following this guide, I'm having this code:
var acs = ActionCodeSettings(
url: 'https://example.com/auth/widget',
androidPackageName: 'com.example',
iOSBundleId: 'com.example',
handleCodeInApp: true,
androidInstallApp: true,
androidMinimumVersion: '12',
);
var emailAuth = 'john.doe#pm.me';
FirebaseAuth.instance
.sendSignInLinkToEmail(
email: emailAuth, actionCodeSettings: acs)
.catchError((onError, stackTrace) {})
.then((value) =>
print('Successfully sent email verification'));
Sending the email works, but when I click on the email, then…
in iOS it opens https://example.com/auth/widget - which is the fallback
in Android it shows a circular loader for about 1s and then it "falls down" and nothing happens
The incoming link handler
FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) {
print('got dynamic link! $dynamicLinkData');
}).onError((error) {
print('error error!');
});
I configured dynamic links in Firebase to point to to.example.com. I also added a manual dynamic link to.example.com/test which opens my app (the got dynamic link! message shows up) - so all seems fine, the problem seems to lie in the link generation.
The link structure I get by email is:
https://to.example.com/?link=https://example-abcd.firebaseapp.com/__/auth/action?apiKey…%26continueUrl%3Dhttps://example.com/auth/widget%26lang%3Den&apn=com.example&amv=12&ibi=com.example&ifl=https://example-abcd.firebaseapp.com/__/auth/action?apiKey%3D…%26continueUrl%3Dhttps://example.com/auth/widget%26lang%3Den
After some more painful hours of debugging and reading documentation I finally found it out. Most of this is in the flutter documentation, but since the documentation has broken links and is a bit all over the place it was hard for me to catch it all!
Android
I needed to decrease the androidMinimumVersion from 12 to 1. Then my app opens and I can receive the dynamic link. No idea why. My android simulator is android version 13 but the app never opened.
Before decreasing the android version I also set the sha256 setting in firebase, using gradlew signingReport documented in this answer. Not sure though this was required.
iOS
I forgot to do all the steps documented in receiving links on iOS section, namely:
add the dynamic links domain into associated domains
add FirebaseDynamicLinksCustomDomains into Info.plist
Overall, I found that to get this feature working was really really hard for me as a Flutter beginner. But I guess a lot of the setup I can re-use as the dynamic links capability seems to be something which comes in handy in the future.
I am attempting to use the snapkit login web api for a hybrid application. I have successfully been able to intercept the access token in the redirectURL. I was wondering if there was a way to get the users Bitmoji using this access_token and either the functions found in login.js or an http get call?
Api docs: https://docs.snapchat.com/docs/login-kit/#web
currently I have the access_token in a deeplinking function on my app.component.ts . I have attempted to push to a new page with the navController and passing in the access_token as a parameter, but this doesn't help when attempting to get the users information.
Thanks in advance for your help.
Here is the Deeplinking where I intercept the access_token using myapp://settings-set/ as the URL redirect and attempt to push a new page with the matching url.
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
this.deeplinks.routeWithNavController(this.nav,{
'/settings-set/:token': SettingsSetPage
}).subscribe((match) => {
// match.$route - the route we matched, which is the matched entry from the arguments to route()
// match.$args - the args passed in the link
// match.$link - the full link data
this.nav.push(SettingsSetPage, {
args: match
});
console.log('Successfully matched route', match.$args);
},
(nomatch) => {
// nomatch.$link - the full link data
console.error('Got a deeplink that didn\'t match', nomatch);
});
});
}
In the setting-set page I recieve the parameter using:
this.args = navParams.get('args');
console.log("this is args", JSON.stringify(this.args));
but don't know how to use the information to get the users information
The Bitmoji API can be very confusing at times. I suggest using Passport, a Node JS tool for OAuth, along with the Ionic framework. Snapchat has a guide that explains how to grab specific fields, such as user name and Bitmoji avatar, from a user's Snapchat profile using passport. You can follow this tutorial to learn how to integrate Node JS into your existing ionic app.
So in conclusion, try following these steps:
Integrate Node JS into your existing ionic app
Install Passport and follow Snapchat's guide for obtaining specific fields from the user's profile
Yes, like Mora said you can use passport which will make your life easier. We also have a sample passport app running here:
From the context you provided it seems like you have generated the code and not the access_token. After you get the code from the redirect url, you need to use the code to generate the access token. Check section 2.5 here.
Once you have the access token you can use that to request information. The crux of this lies in setting the "scope" correctly. To get the Bitmoji avatar make sure you set your scope to this at the very least:
var scope = ['https://auth.snapchat.com/oauth2/api/user.bitmoji.avatar'];
Hope this helps!
My app is based on this code sample from Google: https://actions-on-google.github.io/actions-on-google-nodejs/classes/conversation_question.deeplink.html
Here is a snippet directly from my code:
app.intent('Default Welcome Intent', conv => {
conv.ask('Great! Looks like we can do that in the app.')
conv.ask(new DeepLink({
destination: 'MyBookApp',
url: 'https://www.mybooksite.com/read/123456789',
package: 'com.mybook.app.reader',
reason: 'handle this for you',
}))
})
// Create a Dialogflow intent with the `actions_intent_LINK` event
app.intent('Get Link Status', (conv, input, arg, status) => {
// possibly do something with status
conv.close('Okay maybe we can take care of that another time.')
})
When I run this app I see "Okay maybe we can take care of that another time." instead of my app being launched.
Is there code missing in my handler for the 'Get Link Status' intent? (I created the intent according to the comment above that line).
Am I passing the wrong params to the DeepLink object? I can't find docs for them anywhere.
Note: My app is definitely coded to handle http deep links including verification with Google Digital Asset Links and the deep link URL I'm testing with works perfectly from other apps.
Any suggestions or help is much appreciated!
Thanks in advance...
Your welcome intent handler is missing an additional call to conv.ask before the deep link call:
conv.ask('Great! Looks like we can do that in the app.')
All responses should have at least a simple response.
We have a chatbot for our website today, that is not build using Google technology. The bot has a JSON REST API where you can send the question to and which replies with the corresponding answers. So all the intents and entities are being resolved by the existing chatbot.
What is the best way to wrap this functionality in Google Assistant / for Google Home?
To me it seems I need to extract the "original" question from the JSON that is send to our webservice (when I enable fullfilment).
But since context is used to exchange "state" I have to find a way to exchange the context between the dialogflow and our own chatbot (see above).
But maybe there are other ways ? Can it (invoke our chatbot) be done directly (without DialogFlow as man in the middle) ?
This is one of the those responses that may not be enough for someone who doesn't know what I am talking about and too much for someone who does. Here goes:
It sounds to me as if you need to build an Action with the Actions SDK rather than with Dialog flow. Then you implement a text "intent" in your Action - i.e. one that runs every time the user speaks something. In that text intent you ask the AoG platform for the text - see getRawInput(). Now you do two things. One, you take that raw input and pass it to your bot. Two, you return a promise to tell AoG that you are working on a reply but you don't have it yet. Once the promise is fulfilled - i.e. when your bot replies - you reply with the text you got from your bot.
I have a sample Action called the French Parrot here https://github.com/unclewill/french_parrot. As far as speech goes it simply speaks back whatever it hears as a parrot would. It also goes to a translation service to translate the text and return the (loose) French equivalent.
Your mission, should you choose to accept it, is to take the sample, rip out the code that goes to the translation service and insert the code that goes to your bot. :-)
Two things I should mention. One, it is not "idiomatic" Node or JavaScript you'll find in my sample. What can I say - I think the rest of the world is confused. Really. Two, I have a minimal sample of about 50 lines that eschews the translation here https://github.com/unclewill/parrot. Another option is to use that as a base and add code to call your bot and the Promise-y code to wait on it to it.
If you go the latter route remove the trigger phrases from the action package (action.json).
So you already have a Backend that process user inputs and sends responses back and you want to use it to process a new input flow (coming from Google Assistant)?
That actually my case, I've a service as a Facebook Messenger ChatBot and recently started developing a Google Home Action for it.
It's quite simple. You just need to:
Create an action here https://console.actions.google.com
Download GActions-Cli from here https://developers.google.com/actions/tools/gactions-cli
Create a JSON file action.[fr/en/de/it].json (choose a language). The file is your mean to define your intents and the URL to your webhook (a middleware between your backend and google assistant). It may look like this:
{
"locale": "en",
"actions": [
{
"name": "MAIN",
"description": "Default Welcome Intent",
"fulfillment": {
"conversationName": "app name"
},
"intent": {
"name": "actions.intent.MAIN",
"trigger": {
"queryPatterns": [
"Talk to app name"
]
}
}
}
],
"conversations": {
"app name": {
"name": "app name",
"url": "https://your_nodejs_middleware.com/"
}
}
}
Upload the JSON file using gactions update --action_package action.en.json --project PROJECT_ID
AFAIK, there only a Node.js client library for Actions-on-google https://github.com/actions-on-google/actions-on-google-nodejs that why you need a Node.js middleware before hitting your backend
Now, user inputs will be sent to your Node.js middleware (app.js) hosted at https://your_nodejs_middleware.com/ which may look like:
//require express and all required staff to build a Node.js server,
//look on internet how to build a simple web server in Node.js
//if you a new to this domain. const {
ActionsSdkApp } = require('actions-on-google');
app.post('/', (req, res) => {
req.body = JSON.parse(req.body);
const app = new ActionsSdkApp({
request: req,
response: res
});
// Create functions to handle requests here
function mainIntent(app) {
let inputPrompt = app.buildInputPrompt(false,
'Hey! Welcome to app name!');
app.ask(inputPrompt);
}
function respond(app) {
let userInput = app.getRawInput();
//HERE you get what user typed/said to Google Assistant.
//NOW you can send the input to your BACKEND, process it, get the response_from_your_backend and send it back
app.ask(response_from_your_backend);
}
let actionMap = new Map();
actionMap.set('actions.intent.MAIN', mainIntent);
actionMap.set('actions.intent.TEXT', respond);
app.handleRequest(actionMap); });
Hope that helped!
Thanks for all the help, the main parts of the solution are already given, but I summarize them here
action.json that passes on everything to fullfilment service
man in the middle (in my case IBM Cloud Function) to map JSON between services
Share context/state through the conversationToken property
You can find the demo here: Hey Google talk to Watson