import_feed

Discover, preview and manage the feeds imported by mod_import_feed.

Administrator accounts cannot run imports. Select an enabled non-administrator account with only the required import permissions. This is checked when saving settings and before polling, including for existing feeds whose account is later promoted to admin.

Model paths

The model exposes read-only GET paths. All paths require use permission for mod_import_feed; denied requests return {error, eacces}. Unknown paths return {error, unknown_path}. Successful m_get/3 calls return {ok, {Value, Rest}}.

Template expressionGET pathValue
m.import_feed.can_select_usercan_select_userWhether the caller may choose an import account.
m.import_feed.listlistFeed maps, newest first, including statistics and article_count.
m.import_feed.get[id]get/<id>One feed map; enoent when missing.
m.import_feed.items[id]items/<id>First page of import history, up to 100 rows.
m.import_feed.history[id][offset]history/<id>/<offset>Map with items, offset, previous, next and has_next.

Feed maps use atom keys and include settings, counters, poll times and is_running. is_zotonic_feed records detected native resource entries: true for native or mixed feeds, false for ordinary feeds, and undefined until known. Empty Atom feeds do not overwrite an earlier detection. use_credentials defaults to false. When true, fetches use host-matched OAuth2 consumer tokens registered for the selected import account. Tokens are not stored in feed settings. Development fetch behavior follows m_site:environment/1. Native import settings are import_depth (0–10, default 1), is_subscribe and is_subscribe_connections (both default false). The subscription flags apply through mod_websub to non-authoritative Zotonic resource imports. Internal lease tokens and saved user groups are omitted. History rows include uri, rsc_id, kind, status and processing times. Rows referring to resources the caller cannot view are filtered out; deleted resources have an undefined rsc_id.

{% for feed in m.import_feed.list %}
    <p>{{ feed.title|escape }}: {{ feed.article_count }} articles</p>
{% endfor %}

Erlang API

Discovery, previews and writes are direct Erlang functions, not model POST paths. The admin screens invoke them through mod_import_feed events.

fetch_resource(Uri, Context) implements the optional rsc_import_fetch handler. It returns undefined for native Zotonic resources (which use the core importer) and unknown URIs, {ok, Id} on refresh, or an error. Known articles require module write permission and resource edit permission from the caller, plus an enabled non-admin import account with permission to edit the article. It refreshes one entry from the current feed, including for paused feeds, using saved settings and WordPress enrichment. Missing entries return feed_entry_not_found. The explicit refresh bypasses checksums but preserves deletion tombstones.

  • discover(Url, Context) returns {ok, Feeds}, where each candidate has url and title, or {error, Reason}. It accepts a website URL or a feed URL.
  • preview(Url, Context) returns {ok, Feed} with at most three example entries, using WordPress enrichment. No resources are imported.
  • preview(Settings, Count, Context) uses atom-keyed settings, such as a map from get/2, and limits the result to at most three entries. With category settings, it also reports target_category, dependent_count and attached_medium per entry.
  • get(Id, Context) returns {ok, Feed} or {error, enoent}.
  • list(Context) returns feed maps. items(Id, Offset, Context) returns up to 100 history rows, with a non-negative integer offset. Both return [] on ACL denial.
  • save(undefined, Input, Context) creates a feed; save(Id, Input, Context) replaces its settings. Both return {ok, Id} or {error, Reason}. The feed URL is immutable.
  • pause(Id, Boolean, Context) pauses or resumes a feed and returns ok or an error.
  • queue(Id, Reimport, Context) marks a feed due and starts background processing. With Reimport = true, it clears entry checksums, preserving source identities and deletion records. It returns ok or an error, does not wait for imports to finish, and does not resume a paused feed.

can_select_user/1 checks both feed access and the account-selection permission. validate_user/2 additionally rejects read-only contexts, missing accounts, resources without user credentials and disabled accounts; it returns {ok, UserId}, {error, eacces} or {error, invalid_import_user}.

These administration functions check module permission; writes also reject read-only contexts. allowed/1 reports module permission only. Exported install/1 and decode/1 are internal schema/worker helpers and do not form an ACL-protected administration API.

Saving settings

save/3 accepts a complete map with binary keys, matching the admin form. Keys are url, title, category_id, content_group_id, guess_category, connections, media_mode, poll_minutes, is_authoritative, use_wordpress, is_paused and user_id. The optional user_id selects an enabled account; selecting another account requires administrator status or use permission for mod_admin_identity. Omission on creation uses the current user; omission on update preserves the saved identity and groups. Submitted group memberships are never accepted. Category and content-group values can be resource IDs or names. Connections are a binary with one predicate=resource per line, or a list of such binaries from the connection picker. At most 50 connections are accepted and duplicates are removed. Media mode is dependent, attached or none, as a binary. Polling accepts 5 to 10080 minutes.

Omitted booleans are false in this API, including use_wordpress; the admin form explicitly enables WordPress enrichment. The defaults for category, media mode and polling are Article, dependent media and 60 minutes. Changing the selected user records that account's groups for future imports. Ordinary settings saves preserve them. Saving makes the feed due immediately unless paused.

{ok, FeedId} = m_import_feed:save(undefined, #{
    <<"url">> => <<"https://example.org/feed/">>,
    <<"title">> => <<"Example articles">>,
    <<"category_id">> => <<"article">>,
    <<"use_wordpress">> => true,
    <<"is_paused">> => true
}, Context).

Common errors include eacces, invalid_settings, feed_url_is_immutable, save_failed_or_duplicate_url and enoent. Discovery and previews also propagate fetch and parse errors. See mod_import_feed for import semantics and notifications.

Edit on GitHub