// In order to use the script,
// you must create a Slack bot
// with the user:read scope and
// generate an accesss token.
// The script will prompt you
// to copy the access token in.
// The token is stored securely
// in the keychain.
let containers = await ContactsContainer.all()
let contacts = await Contact.all(containers)
let users = await loadSlackUsers()
for (user of users) {
let profile = user["profile"]
let phone = trimPhone(profile["phone"])
if (phone.length <= 0) {
continue
}
let contact = contacts.find(e => {
return e.phoneNumbers
.filter(p => trimPhone(p.value) == phone)
.length > 0
})
let firstName = profile["first_name"]
if (firstName == null) {
continue
}
if (contact == null) {
let lastName = profile["last_name"]
contact = new Contact()
contact.givenName = firstName
contact.familyName = lastName
contact.phoneNumbers = [{
"label": "Work",
"value": phone
}]
await update(contact, user)
Contact.add(contact)
log("Added " + firstName)
} else {
await update(contact, user)
Contact.update(contact)
log("Updated " + firstName)
}
}
Contact.persistChanges()
async function update(contact, user) {
contact.image = await image(contact, user)
contact.socialProfiles = socialProfiles(contact, user)
}
function socialProfiles(contact, user) {
let all = contact.socialProfiles || []
let idx = all.findIndex(e => {
return e["label"] == "Slack"
})
let url = "slack://user?team="
+ user["team_id"]
+ "&id=" + user["id"]
let entry = {
"label": "Slack",
"service": "Slack",
"username": user["name"],
"url": url
}
if (idx != -1) {
all[idx] = entry
} else {
all.push(entry)
}
return all
}
async function image(contact, user) {
let profile = user["profile"]
let imgURL = profile["image_192"]
let imgReq = new Request(imgURL)
return await imgReq.loadImage()
}
async function loadSlackUsers() {
let token = await getToken()
let baseURL = "https://slack.com/api/users.list"
let url = baseURL + "?token=" + token
let req = new Request(url)
let json = await req.loadJSON()
let users = json["members"]
return users
}
async function getToken() {
let key = "import_contacts.slack.token"
if (Keychain.contains(key)) {
return Keychain.get(key)
} else {
let alert = new Alert()
alert.title = "Paste access token"
alert.message = "Create a Slack bot with the users:read scope, generate an access token and copy it here."
alert.addTextField("Token")
alert.addAction("Save in keychain")
alert.addCancelAction("Cancel")
let idx = await alert.present()
if (idx == -1) {
return null
}
let val = alert.textFieldValue(0)
if (val != null && val.length > 0) {
Keychain.set(key, val)
return val
} else {
return null
}
}
}
function trimPhone(phone) {
let result = phone
result = result.replace(/ /g, "")
if (result.startsWith("+45")) {
return result.slice(3)
} else {
return result
}
}