@@ -305,6 +305,65 @@ def set_weighted_cname_record(
305305 )
306306 return self .create_dns_record (new_record )
307307
308+ def append_txt_record (self , name : str , content : str , ttl : int = 60 ) -> bool :
309+ """Append to a TXT RRset — fetches all existing values and UPSERTs the full set."""
310+ hosted_zone_id = self ._ensure_hosted_zone_id (name )
311+ if not hosted_zone_id :
312+ return False
313+
314+ normalized_name = self ._normalize_record_name (name )
315+ quoted_content = f'"{ content } "'
316+
317+ # Fetch existing TXT RRset directly — get_dns_records only returns the first value
318+ paginator = self .client .get_paginator ("list_resource_record_sets" )
319+ existing_rrset = None
320+ try :
321+ for page in paginator .paginate (HostedZoneId = hosted_zone_id ):
322+ for record_set in page ["ResourceRecordSets" ]:
323+ if record_set ["Name" ] == normalized_name and record_set ["Type" ] == "TXT" :
324+ existing_rrset = record_set
325+ break
326+ if existing_rrset :
327+ break
328+ except Exception as e :
329+ print (f"Error fetching existing TXT records: { e } " , file = sys .stderr )
330+ return False
331+
332+ existing_values = []
333+ if existing_rrset :
334+ existing_values = [rr ["Value" ] for rr in existing_rrset .get ("ResourceRecords" , [])]
335+ ttl = existing_rrset .get ("TTL" , ttl )
336+
337+ if quoted_content in existing_values :
338+ print (f"TXT record already contains { content } " )
339+ return True
340+
341+ all_values = existing_values + [quoted_content ]
342+ print (f"Appending TXT value for { name } : { len (all_values )} total entries" )
343+
344+ change_batch = {
345+ "Changes" : [
346+ {
347+ "Action" : "UPSERT" ,
348+ "ResourceRecordSet" : {
349+ "Name" : normalized_name ,
350+ "Type" : "TXT" ,
351+ "TTL" : ttl ,
352+ "ResourceRecords" : [{"Value" : v } for v in all_values ],
353+ },
354+ }
355+ ]
356+ }
357+
358+ try :
359+ response = self .client .change_resource_record_sets (
360+ HostedZoneId = hosted_zone_id , ChangeBatch = change_batch
361+ )
362+ return response .get ("ChangeInfo" , {}).get ("Status" ) in ["PENDING" , "INSYNC" ]
363+ except Exception as e :
364+ print (f"Error appending TXT record: { e } " , file = sys .stderr )
365+ return False
366+
308367 def create_dns_record (self , record : DNSRecord ) -> bool :
309368 """
310369 Create a DNS record.
0 commit comments