How do we rank contact methods across different method types?

As of today, a necessity across almost all of the data Connect 211 ingests is to prioritize the order in which phone numbers are displayed. We receive up to 11 phone numbers (or more) per resource from certain data sources. We are able to prioritize those on a per-source basis so that we always know in which order they should be displayed. In other words, we always know which number help-seekers should call first. Frequently, we filter most of the other numbers out, but knowing and encoding those priorities is the key to success here.

However, we’re only able to prioritize contact methods within types. I can prioritize phone numbers, and I can prioritize URLs, but I cannot prioritize them together. There are use cases for doing so. For example, consider this sentiment:

Try the main number first, otherwise email us. If neither works, fallback to these other two phone numbers.

As a creator of user facing solutions, I’d love a machine readable queue that tells me whether I should prioritize showing a phone number or URL to users for the next step.

A possible solution from a technical standpoint.

If my proposal to add an email object is accepted, we would then have denormalized objects for phone, url, and email. What if we consolidate those into a contact_method table? Different contact methods would be delineated by types of phone, url, email, and whatever else comes up in future.

I see two main reasons for doing this:

  1. It’s more extensible. Adding other or new contact methods in future involves adding a new type, not a whole new object. Put another way, it would trigger a minor version upgrade instead of a major version upgrade.
  2. Having all methods in one place would set the stage for easier, machine readable ways to express which contact methods users should use, and in what order.

Perks:

  • Standardized way to communicate all contact methods
  • More easily extensible
  • Allows ranking/prioritize contact methods across different types

Problems:

  • May not be as intuitive to understand at first glance
  • Enumerated lists like phone.type would change depending on the contact method type (i.e. phone vs url). Or, considered another way, phones may have necessary fields that preclude them from being easily stored along side other contact methods.

What’s next?

I’m eager for feedback on this idea.

  1. What are other methods we could use to solve ranking/prioritization among contact methods?
  2. How might we use attributes to solve this problem?
  3. Are there other uses-cases that support or negate this presumed need?

@mrshll @devin @sasha

Short answer: Big, big +1 to this idea.

I think this is important. While I think that having separate objects for phones, emails, etc. attached to other objects directly has worked for HSDS in the past; it’s exactly these types of use cases that the concept of something like a contact_point or contact_method covers.

This is done in other Standards as well, the best example being Open Contracting:

I think there’s two things to consider here:

  • What can we do in the short-medium term, within the context of a MINOR upgrade?
  • How should we re-model HSDS to cover these cases when it does come time for a MAJOR upgrade?

In terms of doing this in a MINOR upgrade; I think that’s fairly straightforward:

  • implement a contact_method (or contact_point, or whatever) schema.
  • ensure that this contact_method schema references existing HSDS schemas where possible e.g. contact_method.phone should be an instance of phone.
  • add a contact_method.weight or contact_method.priority property, with an appropriate description. This makes querying for this very straightforward.
  • add contact_methods as a property on relevant schemas
  • mark older properties such as service.phones as deprecated in the schema. This means they’re not removed, which preserves backwards compatability but encourages people to use the newer properties. Deprecating properties is a feature of JSON Schema 2020-12, so we can take advantage of this here. I believe most general-purpose validators which speak JSON Schema 2020-12 should pick up on this and issue warnings (not errors!) to data which uses deprecated fields.

I support this idea whole-heartedly, but here’s some direct answers to your questions:

  1. What are other methods we could use to solve ranking/prioritization among contact methods?

Without a contact_method schema, one alternate way to do this would be to create an object or property which models the weighting specifically and references the id fields of the other objects. I think this would be quite clunky, and still involves adding a new object or property to all the schemas.

Another way would be to add a weighting or priority property to the other schemas themselves e.g. phone.weight or phone.priority… but I don’t like this either. A phone or an email with a weight doesn’t make sense by itself, and the weighting/priority might be relational and depend on the context. There might be a case where a particular email object is the top-ranked contact point for one service, but might be second to a separate contact point for another service. Much better to encapsualte these into a contact_method which describes a single contact point for that service/organizatin/location and its priority compared to its neighbours.

  1. How might we use attributes to solve this problem?

I think there are multiple ways to use attributes here. For me, the most intuitive would be to have the attribute atop the object you’re describing contact points for e.g. service, and use attributes.label to describe that this is a weighting of contact points, and then use attributes.value to describe the actual weighting.

Again, I think this is not preferable to having a contact_point schema, as implementors would need to agree on the label; at which point it’s a case that something like this should just be a feature of the Standard.

  1. Are there other uses-cases that support or negate this presumed need?

Having a single contact_point encapsulate phone, email, etc. would also allow for cases where e.g. the contact point is “the front desk” or “this named role”, and have different methods of contact for that contact point e.g. “The Front Desk has this email and this phone number”. At the moment, Organizations just have arrays of phone numbers, uris, and an email attached. Having this modelled explicitly as a “Contact Point” adds semantic meaning to these things as grouping different contact methods together.

Of course, one could then say that we have the same issue again now: how do we choose whether to use contact_point.email or contact_point.phone for the front desk, but I think this is less of an issue than ranking the individual contact points themselves as you note in the use case; for cases where this is needed it could be modelled as a separate contact point with its own weighting. If it becomes super important to rank methods within a single contact point, this could also be achieved.

If I’m understanding correctly,contact_pointin OCDS refers to a person or entity that has a phone and email, but it’s not clear to me that OR does or should think of contacts as entities that have phone or email. The way that I think about it is that organizations have contact methods rather than contact points. A phone is a method, an email is a method, etc, and therefore a contact object should not have both. Naming phone and email is also not extensible in case other contact methods arise. I would suggest a simple abstraction of contact, eg:

contact: {

method: ‘phone’,

object: {phone object}

priority: [1…],

name: str,

notes: str

}

where name and notes are optional, method isone of [phone, email, url, other?], and object would be phone or email model. priority should also probably be optional. method and object would be required. (admittedly object probably needs a better name)

Relaying a point here from @klambacher (who should check to see whether I’ve captured it correctly):

It might make sense to standardize a way to specify the context / purpose of a contact method – in Kate’s language, the “pathway” that it’s associated with – whereas priority may actually be problematic. Priority is an opinion (of the organization about its own services, or of the intermediary about another organization’s services) and flattened out of context this might actually have a negative effect on accessibility. If we specify how to indicate what purpose or “pathway” a given contact method has, then any given implementation might still have an opinion about which method to prioritize how – but the point is that this decision would be made in a specific context which is appropriate in ways that a Priority ranking might not be.

@klambacher did I get this right, and @skyleryoung what do you think about that