Search code examples
rubyrss

How to specify enclosure in Ruby RSS library?


I am trying to use the Ruby RSS library to build an RSS feed for a podcast. I am supplying values for an enclosure, but the enclosure is not being added to the feed and fails silently.

What do I need to do in order for the enclosure to be included in the feed item?

rss = RSS::Maker.make("atom") do |maker|
  maker.channel.id = "my_channel"
  maker.channel.updated = Time.now.to_s
  maker.channel.author = "me"
  maker.channel.title = "my channel"

  maker.items.new_item do |item|
    item.title = "my episode"
    item.id = "my_episode"
    item.updated = Time.now.to_s

    item.enclosure.url = "https://example.com"
    item.enclosure.type = "audio/mpeg"
    item.enclosure.length = 123
  end
end

Output:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"        
  xmlns:dc="http://purl.org/dc/elements/1.1/">   
  <author>                                       
    <name>me</name>                              
  </author>                                      
  <id>my_channel</id>                            
  <title>my channel</title>                      
  <updated>2024-05-11T12:09:06+01:00</updated>   
  <entry>                                        
    <id>my_episode</id>                          
    <title>my episode</title>                    
    <updated>2024-05-11T12:09:06+01:00</updated> 
    <dc:date>2024-05-11T12:09:06+01:00</dc:date> 
  </entry>                                       
  <dc:date>2024-05-11T12:09:06+01:00</dc:date>
</feed>

Solution

  • Your issue is the usage of the Atom maker. Atom does not recognize "enclosure" the same way as the RSS Specs.

    Atom can have an "enclosure" by way of a link rel attribute (Spec)

    So to use the Atom maker you should be able to do something like

    item.link.rel = "enclosure"
    item.link.href = "https://example.com"
    item.link.type = "audio/mpeg"
    item.link.length = 123
    

    Which will generate a Link node like:

     <link rel="enclosure" type="audio/mpeg" length="123" href="https://example.com"/>
    

    If you want to generate a true enclosure node then you will need to use one of the RSS Makers. For Example 2.0 (Spec). Then your existing code will work as anticipated:

    RSS::Maker.make("2.0") do |maker|
      # ...
      maker.items.new_item do |item|
        #...
        item.enclosure.url = "https://example.com"
        item.enclosure.type = "audio/mpeg"
        item.enclosure.length = 123
      end
    end 
    

    This will generate an enclosure node like:

    <enclosure url="https://example.com" length="123" type="audio/mpeg" />