Generate referral short links using Branch SDK android - android

I want to implement a referral system in my app using branch SDK. I want to generate a short link with my static custom endpoint (https://app.link/ABC123) for each user which can be shared by other users. I can do this by setting alias on LinkProperties. But using alias with BUO.showShareSheet gives an error.
Can I use an alias with BUO.showShareSheet?
Should the Canonical identifier unique for each URL?
Is it possible to set multiple channels using LinkProperties?
Does the same URL generate every time if all arguments are same for BUO & LinkProperties?

1. Can I use an alias with BUO.showShareSheet?
You can definitely use alias with the showShareSheet method. Here is the code I used to generate and share an alias link
final BranchUniversalObject branchUniversalObject = new BranchUniversalObject()
.setCanonicalIdentifier("/1234")
.setTitle("Test for alias")
.setContentDescription("Your friend has invited you to check out my app!") .setContentImageUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Branch_Metrics_logo_color.png/1200px-Branch_Metrics_logo_color.png")
.addContentMetadata("var1", "abc")
.addContentMetadata("var2", "def");
LinkProperties linkProperties = new LinkProperties()
.setChannel("Facebook")
.setFeature("Sharing")
.setAlias("aliastest");
ShareSheetStyle ss = new ShareSheetStyle(MainActivity.this, "Check this out!", "This stuff is awesome: ")
.setCopyUrlStyle(ContextCompat.getDrawable(this, android.R.drawable.ic_menu_send), "Copy", "Added to clipboard")
.setMoreOptionStyle(ContextCompat.getDrawable(this, android.R.drawable.ic_menu_search), "Show more")
.addPreferredSharingOption(SharingHelper.SHARE_WITH.FACEBOOK)
.addPreferredSharingOption(SharingHelper.SHARE_WITH.EMAIL)
.addPreferredSharingOption(SharingHelper.SHARE_WITH.MESSAGE)
.addPreferredSharingOption(SharingHelper.SHARE_WITH.HANGOUT)
.setAsFullWidthStyle(true)
.setSharingTitle("Share With");
branchUniversalObject.showShareSheet(this, linkProperties, ss, new Branch.BranchLinkShareListener() {
#Override
public void onShareLinkDialogLaunched() {
}
#Override
public void onShareLinkDialogDismissed() {
}
#Override
public void onLinkShareResponse(String sharedLink, String sharedChannel, BranchError error) {
}
#Override
public void onChannelSelected(String channelName) {
}
});
But please note, if you try to generate a link with the same alias and different link parameters, you will receive an alias conflict error and the showShareSheet method would, in turn, give you an error.
2. Should the Canonical identifier unique for each URL?
The canonicalIdentifier or canonicalUrl parameter greatly improves the content analytics data Branch captures. Branch suggests that it should be unique to that piece of content. It, in turn, helps Branch dedupe across many instances of the same thing. Suitable options: a website with pathing, or a database with identifiers for entities.
3. Is it possible to set multiple channels using LinkProperties?
You cannot set multiple channels for a single link. The channel tag is used to signify the route that your link reaches users. Hence, there can be only one channel.
4. Does the same URL generate every time if all arguments are same for BUO & LinkProperties?
If all the BranchUniversalObject properties and link properties are exactly the same, the generateShortUrl and showShareSheet will return the same link.

Related

Sends a text message to a specific number phone

I got App api_id, App api_hash and Production configuration from telegram.org, I need to use from this method messages.sendMessage for Sends a text message to a specific number phone's telegram(for example: +1888888). How can I use from this method. Is there any a simple sample?
I suggest you using a top-layer library over MTProto to make things easier. For example you can use Telethon. You should use SendMessageRequest in order to send message. After creating a client you can call it like this (in newest version of Telethon the phone number is resolved automatically):
from telethon.tl.functions.messages import SendMessageRequest
client(SendMessageRequest('phone_number', 'hello'))
If you're using TDLib, you may use this function (taken from here) or a similar one:
private static void sendMessage(long chatId, String message) {
// initialize reply markup just for testing
TdApi.InlineKeyboardButton[] row = {new TdApi.InlineKeyboardButton("https://telegram.org?1", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?2", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?3", new TdApi.InlineKeyboardButtonTypeUrl())};
TdApi.ReplyMarkup replyMarkup = new TdApi.ReplyMarkupInlineKeyboard(new TdApi.InlineKeyboardButton[][]{row, row, row});
TdApi.InputMessageContent content = new TdApi.InputMessageText(new TdApi.FormattedText(message, null), false, true);
client.send(new TdApi.SendMessage(chatId, 0, false, false, replyMarkup, content), defaultHandler);
}
Don't forget that, you need to add each phone number to user's Telegram contacts first to get the chatId. It can be achieved by passing an array of phone numbers to this function:
---functions---
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts

Endpoints generated client library

My problem is that I migrated to Endpoints v2, and at some point down the line my GCM registration code stopped working.
Stopped working? More specifically, the generated client library is attempting to send a POST request in the form provided in the top line of this image:
The second line is what happens when I send the request myself manually with Postman (changing it so that it sends the data in the URL fragment instead of in the query string). This works, and is added to my database.
The registration is sent using the standard API builder:
Registration.Builder builder = new Registration.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null)
.setRootUrl("https://"+Constants.PROJECT_ID+".appspot.com/_ah/api/");
regService = builder.build();
regService.registerDevice(gcmRegistrationId).execute();
The endpoint itself looks like this:
#ApiMethod(name = "registerDevice", httpMethod = "post")
public void registerDevice(#Named("regId") String regId) {
if(findRecord(regId) != null) {
log.info("Device " + regId + " already registered, skipping register");
return;
}
RegistrationRecord record = new RegistrationRecord();
record.setRegId(regId);
ofy().save().entity(record).now();
}
How can this be resolved?
My code is being deployed and generated with the following commands:
gradlew endpointsOpenApiDocs
gcloud endpoints services deploy backend\build\endpointsOpenApiDocs\openapi.json
gradlew appengineDeploy
gradlew endpointsClientLibs
If you want the parameter to be a query string, it should be marked #Nullable as well. This will tell take the parameter out of the path. Looks like there is some mismatch between the configuration in the old and new frameworks, but it is more correct to use #Nullable for query parameters and omit it for path parameters.

Cloud Endpoints generate entity key inside of Android/iOS client libs

Is there a way inside of Android Java to create an Entity Key?
For example, inside the Cloud Endpoints Java module code you can do this:
Key<User> userKey= Key.create(User.class, userId);
or with an Ancestor:
Key<Post> postKey= Key.create(userKey, Post.class, postId);
How can you do the above in the Android generated client library? I want to see if I can create a key in Android and pass it to an API method (probably as a websafeKey userKey.getString()).
BONUS: How can you do this with the objective-C Cloud Endpoints client library?
I doubt you want either the datastore nor objectify code in your Android App. That simply not where that belongs. So the way to go is to look at the source of the KeyFactory. In the method keyToString() we can see that most of the magic happens in the class KeyTranslator in method convertToPb().
Here's the code of convertToPb:
public static Reference convertToPb(Key key) {
Reference reference = new Reference();
reference.setApp(key.getAppId());
String nameSpace = key.getNamespace();
if (!nameSpace.isEmpty()) {
reference.setNameSpace(nameSpace);
}
Path path = reference.getMutablePath();
while (key != null) {
Element pathElement = new Element();
pathElement.setType(key.getKind());
if (key.getName() != null) {
pathElement.setName(key.getName());
} else if (key.getId() != Key.NOT_ASSIGNED) {
pathElement.setId(key.getId());
}
path.addElement(pathElement);
key = key.getParent();
}
Collections.reverse(path.mutableElements());
return reference;
}
And here's the code of keyToString()
public static String keyToString(Key key) {
if (!key.isComplete()) {
throw new IllegalArgumentException("Key is incomplete.");
} else {
Reference reference = KeyTranslator.convertToPb(key);
return base64Url().omitPadding().encode(reference.toByteArray());
}
}
Now what you want to do, is to replace the Key stuff in convertToPb with "normal" parameters (type, name/key, parent type, parent name/key) and thus rewrite the method to create a websafeKey without an actual Key object.
It would be much easier though if your app engine API simply accepted the ids and you'd recreate the key on the appengine side of things. My APIs are usually structured like
/user/<userId>/post/<postId>
if i assume an Entity that looks like this
#Entity public class Post {
#Parent Ref<User> user
#Id id; }
Regarding the bonus: What (the heck) is an Objectify Cloud Endpoint? I know Cloud Endpoints and Objectify, but i have not heard of a product that combines the two.

Gigya ids.setAccountInfo error Schema validation failed

i am trying to set account data
i use ids.setAccountInfo
GSObject param = new GSObject();
GSObject profile = new GSObject();
param.put("UID", user.getString("UID"));
profile.put("firstName", "FirstName");
param.put("profile", profile);
GSAPI.getInstance().sendRequest("ids.setAccountInfo", param, new GSResponseListener() {
#Override
public void onGSResponse(String s, GSResponse gsResponse, Object o) {
Log.d("ids.setAccountInfo", "----------------------------");
Log.d("ids.setAccountInfo", "s " + s);
Log.d("ids.setAccountInfo", "gsResponse " + gsResponse);
Log.d("ids.setAccountInfo", "----------------------------");
}
}, null);
and have response
errorCode:400006
errorMessage:Invalid parameter value
errorDetails:Schema validation failed
data:{"validationErrors":[{"message":"write access mode violation","fieldName":"profile.firstName","errorCode":400025}],"statusCode":400,"errorMessage":"Invalid parameter value","time":"2015-08-13T11:48:14.664Z","errorDetails":"Schema validation failed","statusReason":"Bad Request","errorCode":400006,"callId":"e0ed6aebea144323b095849ae3ed40ee"}
If I send empty profile or not send it then success
errorCode:0
errorMessage:null
errorDetails:null
data:{"statusCode":200,"errorCode":0,"time":"2015-08-13T11:53:19.738Z","callId":"e59b00cd09bf48a398586219f817930d","statusReason":"OK"}
Since the call to ids.setAccountInfo is done from a client side (presuming android SDK is used) while the profile schema for these fields write access is 'serverOnly' or 'clientCreate'. In order for this to work these fields needs to have the 'clientModify' write access.
Get the schema with ids.getSchema and look in fields write access.
It is possible to change that with a call to ids.setSchema, look in link for further details.
writeAccess - Specifies whether to allow unsigned requests to write into this field. This property applies when using the ids.getAccountInfo method, or when setting fields through the usage of a Screen-Set. The supported values are:
"serverOnly" (default) - Only signed requests coming from the server are allowed.
"clientCreate" - Unsigned requests coming from the client are allowed to write into this field, only if it wasn't set before.
"clientModify" - Unsigned requests coming from the client are allowed to write into this field and modify existing values.

What does Device Id mean Azure Push Notifications in Xamarin Android? How to get it?

We are using Azure Mobile Services to Push notifications to a Xamarin Android and a Xamarin iOS and a Windows Universal App. The Windows Universal App has plenty of documentation around what we need, although we haven’t had a chance to implement it yet. However, both Xamarin Android and iOS are missing all documentation around Push Notifications. If you go to http://azure.microsoft.com/en-us/documentation/services/mobile-services/ and select Xamarin Android or Xamarin iOS and .NET Backend there are zero links for documentation around these APIs. After digging around a ton yesterday I found this: http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-push/ and http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-push/ both which were last updated in September of last year. The documentation was promised to be updated over 5 months ago.
When I use the Xamarin Component from Microsoft for Azure Mobile Services: http://components.xamarin.com/view/azure-mobile-services/ I am able to get the MobileServiceClient up and running, but not the Push notifications.
The API:
Push pushManager = MobileService.GetPush();
string deviceId = "what is this???";
//Option 1:
pushManager.RegisterNativeAsync(deviceId);
//Option 2:
GcmRegistration googleNotificationRegistration = new GcmRegistration(deviceId);
pushManager.RegisterAsync(googleNotificationRegistration);
Documentation I’m using:
Push.RegisterAsync:
https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.mobileservices.push.registerasync.aspx
GcmRegistration: I can’t find any documentation for this class
Registration (Base class for GcmRegistration):
https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.mobileservices.registration.aspx
Note: the parameter for Registration is not named deviceId it is named channelUri
Push.RegisterNativeAsync:
https://msdn.microsoft.com/en-us/library/dn643553.aspx
Note: the parameter of RegisterNativeAsync is not named deviceId it is named channelUri
My question is simple:
What is deviceId supposed to be? And how do I get it?
All the documentation above is for Winodws Universal Apps not for Xamarin Apps on Mono.
In the writing up of this question I have found articles about "Get Started with Notification Hubs":
Xamarin iOS - http://azure.microsoft.com/en-us/documentation/articles/partner-xamarin-notification-hubs-ios-get-started/
Xamarin Android - http://azure.microsoft.com/en-us/documentation/articles/partner-xamarin-notification-hubs-android-get-started/
Are these the example I should be using? They look old and the Android one mentions nothing about Azure Mobile Services. Should I not even be using the Azure Mobile Services Xamarin Component for Android?
tl;dr
deviceId should be just the GCMRegistrationId.
I looked into the source code of the implementations of the component DLLs and also Android SDKs.
Firstly, let's take a look to your option 1 and option 2 behind the scene. Basically both eventually do the same job of creating a GcmRegistration and passing it the internal RegistrationManager.
public Task RegisterAsync (Registration registration)
{
if (registration == null) {
throw new ArgumentNullException ("registration");
}
if (string.IsNullOrWhiteSpace (registration.PushHandle)) {
throw new ArgumentNullException ("registration.deviceId");
}
return this.RegistrationManager.RegisterAsync (registration);
}
public Task RegisterNativeAsync (string deviceId, IEnumerable<string> tags)
{
if (string.IsNullOrWhiteSpace (deviceId)) {
throw new ArgumentNullException ("deviceId");
}
GcmRegistration registration = new GcmRegistration (deviceId, tags);
return this.RegistrationManager.RegisterAsync (registration);
}
Then, one of the API calls that I can find involving the Registration.PushHandle (which is the deviceId you passed) is as below
public async Task<IEnumerable<Registration>> ListRegistrationsAsync (string deviceId)
{
MobileServiceHttpResponse mobileServiceHttpResponse = await this.client.HttpClient.RequestAsync (HttpMethod.Get, string.Format ("/push/registrations?deviceId={0}&platform={1}", new object[] {
Uri.EscapeUriString (deviceId),
Uri.EscapeUriString (Platform.Instance.PushUtility.GetPlatform ())
}), this.client.CurrentUser, null, true, null, MobileServiceFeatures.None);
return JsonConvert.DeserializeObject<IEnumerable<Registration>> (mobileServiceHttpResponse.Content, new JsonConverter[] {
new RegistrationConverter ()
});
}
I have then switched to Android Mobile Services SDK to look for similar code to find some hints. Sadly, it is found called pnsHandle in android but still no hints what it is.
/**
* Registers the client for native notifications with the specified tags
* #param pnsHandle PNS specific identifier
* #param tags Tags to use in the registration
* #return The created registration
* #throws Exception
*/
public Registration register(String pnsHandle, String... tags) throws Exception {
if (isNullOrWhiteSpace(pnsHandle)) {
throw new IllegalArgumentException("pnsHandle");
}
Registration registration = PnsSpecificRegistrationFactory.getInstance().createNativeRegistration(mNotificationHubPath);
registration.setPNSHandle(pnsHandle);
registration.setName(Registration.DEFAULT_REGISTRATION_NAME);
registration.addTags(tags);
return registerInternal(registration);
}
Finally, I guess the below example code from http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-push/#update-app should be calling the same API which now explain everything, i.e. deviceId is just the GCMRegistrationId.
#Override
public void onRegistered(Context context, final String gcmRegistrationId) {
super.onRegistered(context, gcmRegistrationId);
new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
try {
ToDoActivity.mClient.getPush().register(gcmRegistrationId, null);
return null;
}
catch(Exception e) {
// handle error
}
return null;
}
}.execute();
}

Categories

Resources