Fix contact creation: assign tag (address book) to new contacts

Starface requires every contact to be assigned to a tag.
- Load tag IDs when fetching address books (folder/all for central,
  folder/private for personal)
- Include tags array in POST /contacts body
- Debug log all discovered tags for troubleshooting

Important: Existing profiles need to reload address books (edit
profile -> load address books -> save) to pick up the tag IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
duffyduck 2026-04-03 18:21:58 +02:00
parent 3e22a40e17
commit ab9c16c69a
1 changed files with 59 additions and 28 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Security.Cryptography; using System.Security.Cryptography;
@ -115,42 +116,62 @@ namespace StarfaceOutlookSync.Services
{ {
var books = new List<StarfaceAddressBook>(); var books = new List<StarfaceAddressBook>();
books.Add(new StarfaceAddressBook // Alle Tags laden - die Starface nutzt Tags als Adressbuch-Zuordnung
{ var allTags = new JArray();
Type = "central",
Name = "Zentrales Adressbuch"
});
var userId = await GetCurrentUserIdAsync();
if (!string.IsNullOrEmpty(userId))
{
books.Add(new StarfaceAddressBook
{
Type = "user",
UserId = userId,
Name = "Persoenliches Adressbuch"
});
}
// Tags als virtuelle Adressbuecher
try try
{ {
var resp = await _http.GetAsync($"{_baseUrl}/contacts/tags"); var resp = await _http.GetAsync($"{_baseUrl}/contacts/tags");
if (resp.IsSuccessStatusCode) if (resp.IsSuccessStatusCode)
{ {
var tags = JArray.Parse(await resp.Content.ReadAsStringAsync()); allTags = JArray.Parse(await resp.Content.ReadAsStringAsync());
foreach (var tag in tags) OnDebug?.Invoke($"Gefundene Tags: {allTags.Count}");
foreach (var t in allTags)
OnDebug?.Invoke($" Tag: {t["name"]} (id: {t["id"]}, alias: {t["alias"]}, owner: {t["owner"]})");
}
}
catch { }
// Zentrales Adressbuch (folder/all)
var allTag = allTags.FirstOrDefault(t => t["name"]?.ToString() == "folder/all"
|| t["alias"]?.ToString()?.Contains("folder.all") == true);
books.Add(new StarfaceAddressBook
{ {
Type = "central",
TagId = allTag?["id"]?.ToString() ?? "",
Name = "Zentrales Adressbuch"
});
// Persoenliches Adressbuch (folder/private mit owner = userId)
var userId = await GetCurrentUserIdAsync();
if (!string.IsNullOrEmpty(userId))
{
var privateTag = allTags.FirstOrDefault(t =>
(t["name"]?.ToString() == "folder/private" || t["alias"]?.ToString()?.Contains("folder.private") == true)
&& t["owner"]?.ToString() == userId);
books.Add(new StarfaceAddressBook
{
Type = "user",
UserId = userId,
TagId = privateTag?["id"]?.ToString() ?? "",
Name = "Persoenliches Adressbuch"
});
}
// Alle weiteren Tags als Adressbuecher anbieten
foreach (var tag in allTags)
{
var tagName = tag["name"]?.ToString() ?? "";
// folder/all und folder/private bereits oben erfasst
if (tagName == "folder/all" || tagName == "folder/private") continue;
books.Add(new StarfaceAddressBook books.Add(new StarfaceAddressBook
{ {
Type = "tag", Type = "tag",
TagId = tag["id"]?.ToString() ?? "", TagId = tag["id"]?.ToString() ?? "",
Name = $"Tag: {tag["name"]}" Name = tagName
}); });
} }
}
}
catch { }
return books; return books;
} }
@ -248,6 +269,16 @@ namespace StarfaceOutlookSync.Services
public async Task<UnifiedContact> CreateContactAsync(UnifiedContact contact, StarfaceAddressBook book) public async Task<UnifiedContact> CreateContactAsync(UnifiedContact contact, StarfaceAddressBook book)
{ {
var sfContact = MapToStarface(contact); var sfContact = MapToStarface(contact);
// Tag zuweisen - die Starface verlangt dass jeder Kontakt einem Tag zugeordnet ist
if (!string.IsNullOrEmpty(book.TagId))
{
sfContact["tags"] = new JArray
{
new JObject { ["id"] = book.TagId }
};
}
var query = ""; var query = "";
if (book.Type == "user" && !string.IsNullOrEmpty(book.UserId)) if (book.Type == "user" && !string.IsNullOrEmpty(book.UserId))
query = $"?userId={book.UserId}"; query = $"?userId={book.UserId}";