lindsey-rix / skyapi-android-voice-hello-world

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bb-constituent-view-android

This repository contains the code for an app that demonstrates how to use the Android Assistant with Blackbaud SKY. This is exploratory and I encountered some limitations with what is currently possible.

This is a native Androud application written in Java and tested on API 28.

Author: Steven Draugel

What it has/does

  1. An Android Assistant intent to look up a constituent by name - this displays a view with the profile picture, display name, address and phone number.
  2. Ability to look up constituents from within the app.
  3. Implements Blackbaud OAuth to login, logout, and refresh the access token when expired.
  4. Includes some SKY UX styling so the app look matches the site users are familiar with, and follows Blackbaud style guidelines.

Login Screen with built in constituent search

Activity view example with links to Google Maps and the phone application

Slice view. If the slice is touched the activity view will open

Included unused code

I experimented with other available Android functionality and found that the implementation of these pieces either did not work well or were still in developer preview.

ConstiuentSliceProvider - Android deeplink intent

I created a slice view that will integrate with the Google app, when no longer in developer preview. This will allow a developer to display content directly in the Google app without the need for internet connectivity.

Limitations found

These limitations exist as of Android 10 (API Level 29) and may change in the future.

Built in intent actions.intent.OPEN_APP_FEATURE

Q: Can I open a view from an installed app using the generic built in actions.intent.OPEN_APP_FEATURE intent

A: No. There is currently a bug preventing this. (Source). As a workaround, I created a node.js service and a custom intent that talks directly to SKY API. (skyapi-android-voice-skill-hello-world)

SKY API - server required

Because SKY API uses developer secrets for API calls, an intermediate server is needed to conceal these secrets. That means that SKY API calls should not be made directly from a mobile application like they are in this demo. Instead, the app should make calls to your server and your server should make the calls to SKY API using the secrets.

Additions wanted (contributions welcome)

  1. Cover all reasonable SKY UX styling
  2. Turn SKY UX styling into a Framework so other Android apps can reuse the code
  3. Turn SKY API into a Framework so other Android apps can reuse the code - ideally would autogenerate this from the SKY API swagger
  4. Unit tests
  5. Localization
  6. Accessibility
  7. Proper UI for "find a constituent"

Further exploration/nice-to-have features

  1. Integration with the Google app
  2. Dark mode

Getting started

Prerequisites:

  1. Set up your SKY application
    1. Go to SKY Developer and create an application
    2. Note the application ID and secret
    3. Add a redirect URI https://host.nxt.blackbaud.com/app-redirect/redirect-androiddemo/android-deeplink
    4. In file strings.xml, set the following properties:
    <string name="subscriptionKey"></string>
    <string name="clientId"></string>
    <string name="redirectUri"></string>
    <string name="clientSecret"></string>
     * Note that the clientSecret is intended to be kept secret and this value should not be 
     included in a production app
    
    1. Add the application to an environment
      1. Go to the home page of environment where you are an environment admin
      2. Go to Control Panel > Applications
      3. Click Add Application
      4. Enter your Application ID and click Save

Debugging

To debug the app - Android Studio

  1. Select the device you'd like to debug, set breakpoints in any file under the java directory, then click debug
    • Note, debugging will degrade performance

Usage

This is licensed under the MIT License. Please feel free to use this app as a starting point for your own app that is available to Blackbaud clients. Keep in mind that there are separate limitations on using Blackbaud's logo, name, and other trademarks as part of your App Store metadata as per Apple's and Blackbaud's terms of service.

This repository contains a proof of concept and, while it can be used as the basic for your own app, you should review it for security best practices prior to publication. For example, for ease of debugging, secrets and stack traces are printed to the console, which should never be done in a production application.

Required changes

Before publishing, you'll want to change the bundle ID, group name, etc. from *com.blackbaud* to your own domain.

There are some TODOs included that should be implemented prior to releasing the app. For example, you should store the user's access token in secure storage rather than as an app property.

Secrets

For simplicity, this app communicates directly with SKY API using the SKY application secret and subscription key. These values should never be exposed in a front end application. Instead, you should have a secure server that makes SKY API requests, and the app should communicate with that server.

OAuth

SKY OAuth requires that you use an https redirect so you'll need to have a simple website or server redirect endpoint for your OAuth redirect url that then redirects into your app. If you don't change the custom URL scheme for this app from the current deeplink, the website used here (https://host.nxt.blackbaud.com/app-redirect/redirect-androiddemo/android-deeplink) will work while you are experimenting, but you'll want to change this prior to publishing your own app.

Here is an example of a SKY UX Angular page that can be used to redirect back to an app:

import {
  Component, OnInit
} from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SkyAppWindowRef } from '@skyux/core';

@Component({
  selector: 'skyapi-oauth-redirect',
  template: `<main>
  <h1>
    You've been redirected here by SKY API
  </h1>
  <p *ngIf="errorMessage">
    Error: {{ errorMessage }}
  </p>
</main>`
})
export class SkyApiOauthRedirectComponent implements OnInit {

  public errorMessage: string;

  constructor(private route: ActivatedRoute, private windowRef: SkyAppWindowRef) {
  }

  public ngOnInit() {

    this.route.queryParams.subscribe(params => {
      let code = params['code'];
      // let state = params['state']; // TODO pass `state` to the request and verify here
      this.errorMessage = params['error'];

      if (!this.errorMessage) {
        let url = `https://host.nxt.blackbaud.com/app-redirect/redirect-androiddemo/android-deeplink?code=${code}`;
        this.windowRef.nativeWindow.location.href = url;
      }
    });
  }
}

About

License:MIT License


Languages

Language:Java 100.0%