fix(amazon): use email and AMAZON type to match old Bose cloud format (#212)

Store the user's email address (not Amazon account ID) in
sourceKey.account and set source type to "AMAZON" so the speaker
firmware recognises Amazon Music sources the same way as the original
Bose cloud.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tobias Gesellchen
2026-05-06 08:23:04 +02:00
committed by GitHub
co-authored by Claude Sonnet 4.6
parent a1d0add5a1
commit d14f4691a6
3 changed files with 10 additions and 6 deletions
+1 -1
View File
@@ -309,7 +309,7 @@ func TestMargeAccountFullExcludesEmptyAmazonSource(t *testing.T) {
t.Fatalf("Failed to write first device DeviceInfo.xml: %v", err)
}
if err := os.WriteFile(filepath.Join(firstDir, "Sources.xml"), []byte(`<sources>
<source id="10006" type="Audio" createdOn="2026-01-01T00:00:00.000+00:00" updatedOn="2026-01-01T00:00:00.000+00:00" displayName="Amazon Music" secret="" secretType="token" sourceproviderid="20">
<source id="10006" type="AMAZON" createdOn="2026-01-01T00:00:00.000+00:00" updatedOn="2026-01-01T00:00:00.000+00:00" displayName="Amazon Music" secret="" secretType="token" sourceproviderid="20">
<sourceKey type="AMAZON" account=""/>
</source>
</sources>`), 0644); err != nil {
+4 -4
View File
@@ -578,7 +578,7 @@ func (s *Server) bridgeAmazonToMarge(accountID string) {
}
for _, acc := range accounts {
log.Printf("[Amazon Bridge] Registering Amazon user %s in Marge for account %s", acc.UserID, accountID)
log.Printf("[Amazon Bridge] Registering Amazon user %s in Marge for account %s", acc.Email, accountID)
// Build the AmazonSecret credential envelope expected by the speaker firmware.
credMap := map[string]interface{}{
@@ -594,7 +594,7 @@ func (s *Server) bridgeAmazonToMarge(accountID string) {
continue
}
_, err = marge.AddSource(s.ds, accountID, acc.UserID, strconv.Itoa(constants.AmazonProviderID), string(credJSON), constants.CredentialTypeToken, acc.DisplayName)
_, err = marge.AddSource(s.ds, accountID, acc.Email, strconv.Itoa(constants.AmazonProviderID), string(credJSON), constants.CredentialTypeToken, acc.DisplayName)
if err != nil {
log.Printf("[Amazon Bridge] Failed to register source in Marge: %v", err)
continue
@@ -623,7 +623,7 @@ func (s *Server) bridgeAmazonToMarge(accountID string) {
cfg.Host = d.IPAddress
cfg.Timeout = 5 * time.Second
c := client.NewClient(cfg)
creds := models.NewAmazonOAuthCredentials(acc.UserID, string(credJSON), acc.DisplayName)
creds := models.NewAmazonOAuthCredentials(acc.Email, string(credJSON), acc.DisplayName)
if err := c.SetMusicServiceOAuthAccount(creds); err != nil {
log.Printf("[Amazon Bridge] Failed to notify speaker %s via OAuth: %v", d.Name, err)
@@ -633,7 +633,7 @@ func (s *Server) bridgeAmazonToMarge(accountID string) {
log.Printf("[Amazon Bridge] Sync notification failed for speaker %s: %v", d.Name, err)
log.Printf("[Amazon Bridge] Falling back to legacy account creation for speaker %s", d.Name)
legacyCreds := models.NewAmazonMusicCredentials(acc.UserID, string(credJSON))
legacyCreds := models.NewAmazonMusicCredentials(acc.Email, string(credJSON))
if err := c.SetMusicServiceAccount(legacyCreds); err != nil {
log.Printf("[Amazon Bridge] Legacy fallback failed for speaker %s: %v", d.Name, err)
} else {
+5 -1
View File
@@ -106,7 +106,11 @@ func ensureTimestamps(s *models.ConfiguredSource) {
func ensureSourceType(s *models.ConfiguredSource) {
if s.Type == "" || (s.SourceKey.Type != "" && s.SourceKey.Type != constants.ProviderAux && s.SourceKey.Type != constants.ProviderBluetooth) {
s.Type = "Audio"
if s.SourceKey.Type == constants.ProviderAmazon {
s.Type = constants.ProviderAmazon
} else {
s.Type = "Audio"
}
}
}