@@ -3,6 +3,7 @@ import { Accounts } from 'meteor/accounts-base';
33import { Meteor } from 'meteor/meteor' ;
44import { Platform } from 'ionic-angular' ;
55import { Sim } from '@ionic-native/sim' ;
6+ import { Contact , ContactFieldType , Contacts , IContactField , IContactFindOptions } from "@ionic-native/contacts" ;
67import { SmsReceiver } from "../ionic/sms-receiver" ;
78import * as Bluebird from "bluebird" ;
89import { TWILIO_SMS_NUMBERS } from "api/models" ;
@@ -12,7 +13,8 @@ import { Observable } from "rxjs";
1213export class PhoneService {
1314 constructor ( private platform : Platform ,
1415 private sim : Sim ,
15- private smsReceiver : SmsReceiver ) {
16+ private smsReceiver : SmsReceiver ,
17+ private contacts : Contacts ) {
1618 Bluebird . promisifyAll ( this . smsReceiver ) ;
1719 }
1820
@@ -64,6 +66,62 @@ export class PhoneService {
6466 }
6567 }
6668
69+ getContactsFromAddressbook ( ) : Promise < string [ ] > {
70+ const getContacts = ( ) : Promise < Contact [ ] > => {
71+ if ( ! this . platform . is ( 'cordova' ) ) {
72+ return Promise . reject ( new Error ( 'Cannot get contacts: not cordova.' ) ) ;
73+ }
74+
75+ const fields : ContactFieldType [ ] = [ "phoneNumbers" ] ;
76+ const options : IContactFindOptions = {
77+ filter : "" ,
78+ multiple : true ,
79+ desiredFields : [ "phoneNumbers" ] ,
80+ hasPhoneNumber : true
81+ } ;
82+ return this . contacts . find ( fields , options ) ;
83+ } ;
84+
85+ const cleanPhoneNumber = ( phoneNumber : string ) : string => {
86+ const phoneNumberNoSpaces : string = phoneNumber . replace ( / / g, '' ) ;
87+
88+ if ( phoneNumberNoSpaces . charAt ( 0 ) === '+' ) {
89+ return phoneNumberNoSpaces ;
90+ } else if ( phoneNumberNoSpaces . substring ( 0 , 2 ) === "00" ) {
91+ return '+' + phoneNumberNoSpaces . slice ( 2 ) ;
92+ } else {
93+ // Use user's international prefix when absent
94+ // FIXME: update meteor-accounts-phone typings
95+ const prefix : string = ( < any > Meteor . user ( ) ) . phone . number . substring ( 0 , 3 ) ;
96+
97+ return prefix + phoneNumberNoSpaces ;
98+ }
99+ } ;
100+
101+ return new Promise ( ( resolve , reject ) => {
102+ getContacts ( )
103+ . then ( ( contacts : Contact [ ] ) => {
104+ const arrayOfArrays : string [ ] [ ] = contacts
105+ . map ( ( contact : Contact ) => {
106+ return contact . phoneNumbers
107+ . filter ( ( phoneNumber : IContactField ) => {
108+ return phoneNumber . type === "mobile" ;
109+ } ) . map ( ( phoneNumber : IContactField ) => {
110+ return cleanPhoneNumber ( phoneNumber . value ) ;
111+ } ) . filter ( ( phoneNumber : string ) => {
112+ return phoneNumber . slice ( 1 ) . match ( / ^ [ 0 - 9 ] + $ / ) && phoneNumber . length >= 8 ;
113+ } ) ;
114+ } ) ;
115+ const flattenedArray : string [ ] = [ ] . concat ( ...arrayOfArrays ) ;
116+ const uniqueArray : string [ ] = [ ...new Set ( flattenedArray ) ] ;
117+ resolve ( uniqueArray ) ;
118+ } )
119+ . catch ( ( e : Error ) => {
120+ reject ( e ) ;
121+ } ) ;
122+ } ) ;
123+ }
124+
67125 verify ( phoneNumber : string ) : Promise < void > {
68126 return new Promise < void > ( ( resolve , reject ) => {
69127 Accounts . requestPhoneVerification ( phoneNumber , ( e : Error ) => {
0 commit comments