Installing, configuring and operating internal announcements inside Salesforce — and reading the numbers that come back.
Everything an administrator does once, before anybody writes an announcement. Roughly thirty minutes, most of it deciding where the reader component belongs.
InfoIQ publishes internal announcements to the people who should see them, inside Salesforce, and reports honestly on how far each one travelled.
An author builds a multi-page announcement, targets it with rules, and publishes it. Readers receive it on the page they are already working on — a record, the home page, or anywhere the utility bar follows them. They read it, they can ask the author a question, and every step is recorded: served, opened, how many pages they got through, where they stopped.
Nothing leaves your org. InfoIQ is a managed package built entirely on the Salesforce Platform. Announcements, reading states and analytics are records in your own org, under your own backup and retention policy. There is no external service, no middleware and no vendor cloud holding a copy.
An announcement is never pushed over what a reader is doing. The component resolves what a reader is entitled to and renders a small card. Opening it is the reader's move. This is a product decision, not a limitation: an announcement that seizes the screen is an announcement people learn to dismiss without reading.
Empty means everyone. An announcement with no targeting rules, an audience with no criteria, and an announcement in audience mode pointing at no audience all reach everybody holding an InfoIQ seat (section 3). Emptiness is never read as a restriction. Section 7 covers what the authoring path does to keep you from reaching that state by accident.
An author or manager builds and publishes announcements and reads analytics. A reader or recipient receives them. An audience is a named, reusable set of targeting criteria shared by several announcements.
Two prerequisites, and a short inventory of what arrives with the package.
| Requirement | Why |
|---|---|
| Permission set groups enabled |
The Announcement_Administrator persona is a permission
set group, not a permission set. Groups are packageable and do not
count against your group limit, but the org must have the feature
enabled to install or uninstall the package.
|
| Enterprise, Unlimited or Developer edition | Custom objects, permission sets and Lightning App Builder are all required. |
| Component | Detail |
|---|---|
| Lightning app | InfoIQ, with Home, Analytics, Audiences, Announcements and Announcement Questions |
| Custom objects | 12, covering announcements, pages, targeting rules, audiences, reading states, questions, analytics snapshots and the diagnostic log, plus one platform event that carries diagnostics out of a rolling-back transaction |
| Permission sets | 4, plus 1 permission set group — section 3 |
| Lightning component | Announcement Host, the one component you place yourself — section 4 |
| Record actions | Publish, Unpublish, Archive and Delete on the announcement record page, each shown only when it applies — section 8 |
| Notification type | Announcement Response, which tells a reader their question was answered — section 9 |
| Scheduled job |
One Schedulable, for log retention. The package does not
schedule it — section 5
|
Reading states and diagnostic log rows sit in your org's data storage, and files attached to announcement pages in your file storage. Both grow with use. Section 14 covers retention, section 15 covers files.
Four permission sets and one group. Assign the set that matches what a person does — never more.
| Assign this | To |
|---|---|
| Announcements User | Everybody who should receive announcements. Grants read on the announcement, its pages and its rules, plus the My Questions tab. Nothing else. |
| Announcements Manager | People who write, target, publish and measure. Grants the InfoIQ app, the builder, the audience library and the analytics tabs. |
| Announcement Log Access | Whoever troubleshoots. Grants the diagnostic log and nothing else — see the warning below. |
|
Announcement Administrator (permission set group) |
Composed of the three above. Assign this rather than assigning them one by one: a field added to a member set reaches this persona on its own. |
| Announcement Data Import | Not a persona. One custom permission that bypasses the validation rules, for a migration. Granted for the run, taken back after — section 5. |
InfoIQ is licensed per seat. A user holds a seat when they can reach the component readers use, whether through Announcements User, Announcements Manager, the Administrator group, a permission set group of your own or a profile. Announcement Log Access and Announcement Data Import grant no seat.
Seat holders are the whole population InfoIQ works with. Targeting, audience estimates and analytics only count them, and a user without a seat never receives an announcement, whatever its rules say. To reach more people, assign Announcements User to them. Rules cannot do it.
A reader holds read access on Announcement__c,
Announcement_Page__c and Announcement_Rule__c,
and a Read share on the announcements they were sent. They hold
no object access at all to reading states or to
questions.
That is deliberate. The children of an announcement are controlled by its parent, so any object permission on them would let a reader enumerate who read what, and read the questions their colleagues asked the author privately. The two reads a recipient is entitled to — the published answers, and their own row — are served by the package's own Apex instead.
Granting Announcement_User_State__c or
Announcement_Question__c to readers turns a private
exchange into a directory of who read what. If a report needs those
figures, give the reporting user the Manager set.
Announcement_Log_Access is the only set that grants the log,
and it exists so the administrator persona can be composed rather than
duplicated. Stack traces and the identity of whoever hit an error are an
operator artefact: an author who could read them would learn what their
colleagues were doing.
One component, four possible homes. This is the only placement decision the package leaves to you, and it decides where announcements appear.
In Lightning App Builder, the component is called Announcement Host. It resolves what the current user is entitled to on the current page and renders a card offering Read or Later. Reading itself opens in a platform modal at application level.
Later only hides the card, which comes back on the reader's next page. Each reader gets one reading. Reaching the end marks it Completed. Closing it partway marks it Dismissed and records the page they stopped on. After either one, the announcement is not offered to them again. When several announcements are live for the same reader, the card offers the highest priority first, then the one that started earliest.
| Placement | Behaviour |
|---|---|
| Utility bar | The usual choice. The component follows the user across every page of the app, so an announcement finds them wherever they are working rather than only on one screen. |
| Record page | The Page Type criterion can name objects, so a message about cases appears on case pages only. Place it in a column where a card does not push the record layout around. |
| Home page | Reaches people at the start of their session, but only if they pass through Home. |
| App page | For a dedicated internal-communications page, if you have one. |
| Property | Use |
|---|---|
| Custom Identifier | A free-text label for this placement. The Custom Identifier criterion matches it, which is how you send a message to one specific spot rather than to a page type. |
That is the only property. The component has no display mode and no debug switch: an announcement is never opened on the reader's behalf, so there is one behaviour and nothing to pick between.
Lightning App Builder lists nine components under the InfoIQ namespace. Only Announcement Host is meant to be placed by an administrator. The other eight are the screens the app builds itself — the home page cards, the targeting editor, the metrics panel — and they appear in the palette only because Salesforce requires a component to be exposed before it can sit on a page, including the package's own. Dropping one of them elsewhere will not break anything, but it will show nothing useful.
If the component sits in the utility bar and on the home page of the same app, a reader arriving on Home can be offered the same announcement twice. Pick one placement per app unless a record-page placement is deliberately targeting a different message.
Two things the package leaves switched off, and why.
The diagnostic log is not a child of any announcement, so nothing cascades it away. One purge runs automatically when an announcement is deleted and takes its entries with it. The other has to be scheduled, and it is the one that catches entries naming no announcement and announcements nobody ever deletes.
System.schedule(
'Announcement Log Purge',
'0 0 3 * * ?',
new aas.AnnouncementLogPurgeSchedule()
);
It drops anything older than 30 days. The package does not schedule this for you: logging works either way, and a job a subscriber did not ask for is a job they did not expect to find.
Announcement_Data_Import carries one custom permission,
Bypass_Announcement_Validations. It lets a save ignore
thirteen of the fifteen validation rules in section 16 — including the
ones that stop a publication date being backdated — so that imported
announcements keep the dates they actually went out on. The other two
still apply, because they keep dates coherent rather than current: a
publish end cannot fall before its start, and a last publish date cannot
fall before the first.
Bypassing validation is a migration tool, not an administrator right. It is deliberately not a member of the Administrator group. The package's own test suite asserts that the running user does not hold it, because a test run that holds a bypass fails later for the wrong reason and reads as a different bug.
What a manager does: compose the content, decide who receives it, publish it, and answer what comes back.
An announcement is a title and an ordered list of pages. Nothing else is required to start.
| Mode | What happens |
|---|---|
| From scratch | An empty announcement. You add pages one at a time. |
| From another announcement | Copies the content of an existing one. Useful for a recurring message; the targeting is not carried over. |
| From a slide deck |
Upload a .pptx and every slide becomes one page, in order
— section below.
|
| Page type | Accepted formats | Notes |
|---|---|---|
| Text | — | Rich text, written in the builder |
| Image | .png .jpg .jpeg .gif .webp |
Uploaded to Salesforce files |
| Video | .mp4 .mov .webm .ogg .m4v |
Uploaded to Salesforce, not linked. The builder has no field for an external URL: the video is a Salesforce file, so it obeys your own sharing and retention. |
A .pptx is a ZIP of XML parts, so InfoIQ counts the slides it
contains and creates one page per slide.
Nothing is converted. Each page shows the picture
Salesforce itself renders for its file preview — the slide, pixel for
pixel, with its layout, its fonts and its diagrams intact. Rebuilding a
slide as HTML would lose all three.
Importing a deck empties the announcement first, then rebuilds it from the slides. It is only possible while the announcement is a Draft. If the file carries no slide, or cannot be read, the import is refused and the announcement is left alone.
Five levels: Low, Medium, High, Urgent, Critical. Priority decides the order: when several announcements are live for the same reader, the highest is offered first. Critical also changes what the reader sees. The card is marked, and the Later button is removed, because leaving a way out on the one announcement that must not wait would say the opposite of what the surface means.
Allow questions in the builder is on by default. Turn it off for an announcement that should not start a conversation, and readers get no way to ask one — section 9.
Two mutually exclusive modes. An announcement targets by criteria written on itself, or by one or more reusable audiences — never both.
| Criterion | Matches on |
|---|---|
| Profile | The reader's profile |
| User | Named users, one by one |
| Role | The reader's role in the hierarchy |
| Group | Membership of a public group |
| Queue | Membership of a queue |
| Application | The Lightning app the reader is currently in |
| Page Type | The kind of page they are on (home, record or app page), and on a record page optionally which objects |
| Custom Identifier | The label set on a specific component placement — section 4 |
Each criterion takes an operator, IN or NOT IN, and a set of values. Criteria are then combined by the announcement's logic mode.
| Logic mode | Meaning |
|---|---|
| Any | Matching one criterion is enough |
| All | Every criterion must match |
| Custom |
A written expression over the numbered criteria, for example
1 AND (2 OR 3). The expression is mandatory in this mode
and the save is refused without it.
|
Application, Page Type and Custom Identifier describe where a reader is, not who they are. When InfoIQ estimates an audience there is no page to speak of, so these criteria are neutral in the estimate — the figure stays a count of people rather than of screens.
Estimate audience in the Targeting tab counts the seat holders the targeting reaches right now, in either mode. Run it before publishing: it is the figure publication will freeze.
An audience is a named set of the same criteria, kept in the Audiences tab and shared across announcements. Attaching several to one announcement combines them with a plain OR: belonging to any one of them is enough. There is no operator on an audience and no nesting.
Audiences are private: an author builds their own library and does not see anybody else's. Delivery and the audience estimate read them regardless of who owns them, because an announcement targeted through an audience nobody can see would otherwise resolve to no criteria — and since empty restricts nothing, it would go org-wide instead of to its audience.
Targeting freezes when an announcement leaves Draft, because the audience size is measured at publication. A shared audience would walk around that freeze, so editing one that a live announcement points at is refused. Duplicate it and edit the copy.
For the same reason the database refuses to delete an audience a live announcement still holds. This is a constraint on the link record, not application code — it cannot be bypassed by a Flow or an API call.
Four statuses, and fifteen validation rules that between them describe exactly what is allowed.
| Status | Meaning |
|---|---|
| Draft | Being written. Content, targeting and logic are all editable — this is the only status in which they are. |
| Published | Delivered between its publish start and its publish end. The audience size is stamped at the moment it is published. |
| Unpublished | Taken down but previously published. It can be published again. |
| Archived | Retired. Its figures continue to feed the Analytics page. |
An announcement that has been published can never return to Draft. If you need to rework the content, duplicate it. This is why the checks below matter: they are the last moment at which a mistake is cheap.
| Frozen once out of Draft | Enforced by |
|---|---|
| Page content | A validation rule on the page |
| Targeting rules | A validation rule on the rule record |
| Rule logic mode | A validation rule on the announcement |
| Targeting mode and chosen audiences | InfoIQ refuses any targeting save outside Draft |
| The audiences themselves | The audience lock, section 7 |
The publication window itself is not frozen: extending an end date on a live announcement is a normal operation, and the home page suggests it when one is about to close.
Archive stops delivery and takes the announcement out of every list of what is running. Its figures stay, on its Metrics tab and on the Analytics page. Delete is offered on the record page whenever the announcement is not Published, so unpublish or archive a live one first. The dialog can also delete the files that this announcement alone was using. A deletion cannot be undone, and section 14 lists what it keeps.
A reader can ask the author a question from inside the announcement, unless the author turned Allow questions off. It is private until the author decides otherwise.
Skipping removes a question from the author's queue without answering it. The reader is not notified. Use it for a question already answered elsewhere, not as a way of refusing one.
Three screens, at three scales: what needs attention today, how one announcement performed, and what everything you have ever sent says about how your organisation reads.
The working view: what is live, what is waiting on you, what needs a decision.
Every live announcement with its coverage (the share of its audience who have closed it, whether they finished it or stopped partway) and how many people were targeted, shown and read. This is the figure that answers "is it landing".
The queue from section 9, oldest first, with Answer and Skip on each row.
InfoIQ raises a suggestion when one of four conditions holds. Its button carries the move out in one click. Not this one dismisses it, and it is not raised again for that announcement until the announcement is published again.
| Suggestion | Raised when |
|---|---|
| Archive it | Coverage has reached 80% or more — the announcement has done its job. |
| Extend it | The window closes within 3 days and coverage is still under 80%. The button pushes the end back by 7 days. |
| Raise its priority | Coverage is under 50% after at least 7 days live, and the priority is below Urgent. The button raises it one level, and the suggestion then stays quiet for 2 days to let the new priority work. |
| Resume it | An unpublished announcement still has an open window and at least one page. |
Open any announcement and switch to Metrics.
From the people it was aimed at, to the ones who read it through:
| Step | Counts |
|---|---|
| Targeted | The audience size measured when it was published |
| Impressions rendered | People the card was actually shown to |
| Opened | People who opened it |
| Read through | People who reached the last page |
The drop between Opened and Read through is usually the most informative number on the screen: it tells you whether the announcement was the right length.
The share of the targeted population that has opened it, day by day since it went live. A curve that flattens early has found everyone it is going to find.
How many readers reached each page, and where they left. A cliff between two pages points at that specific page, not at the announcement as a whole.
Until an announcement has been shown 50 times, the tab carries a warning that its shares still move a lot. The figures are shown all the same. On one announcement, a small number is still information.
Patterns across the whole corpus — including announcements that have since been deleted.
Before an announcement is deleted, InfoIQ writes a snapshot of its figures. The snapshot carries counts and distributions only, never a reader. The Analytics page reads live announcements and snapshots through the same shape, so deleting an announcement removes its contents without removing what it taught you.
| Measure | Answers |
|---|---|
| The hook | Of a hundred readings served, how many were opened and how many concluded |
| The half-life | How fast an announcement reaches its audience in the days after going live, over a 30-day horizon. Finished runs only. |
| Length | How many readers reach the last page, by page count — the cost of a long announcement |
| The page-by-page journey | How many are still there on each page, across every announcement that has that page |
| Where readings stop | How far readers get, in tenths, so announcements of any length sit on one axis |
| What video changes | Whether announcements carrying a video are read further than those that do not |
| Targeting width | Whether narrow announcements are read more attentively than broad ones |
Here a measure stays silent and says not enough rather than showing a figure. The hook, the half-life and where readings stop need 50 readings. Every band or point built from announcements (length, video, the journey, targeting width) needs 5 announcements, and draws its middle half only from 10. A rate over four announcements is noise, and nobody should build a policy on it.
The page covers the last 12 months, the last 24 months or the current fiscal year, and Refresh recomputes it.
The home page and the Metrics tab can show different percentages for the same announcement. This is by design, and it is worth understanding before somebody reports it as a bug.
| Screen | Divides by |
|---|---|
| Home page | A live estimate. The targeting is re-resolved against the org as it is right now. |
| Metrics tab | The audience size frozen at publication and stored on the announcement. |
Both are correct and they answer different questions. The frozen figure is what the announcement was aimed at, and it is the honest denominator for judging the campaign — it does not move under you when somebody joins or leaves a team. The live estimate answers "if I published this today, who would get it".
They diverge when the population behind the targeting changes after publication: people join a profile, leave a group, are deactivated. A large divergence is a signal, not an error — it means the audience you aimed at is no longer the audience that exists.
Read the live estimate and write that, rather than typing a number. A stored figure the live targeting cannot reach produces coverage above 100% on one screen while the other looks normal.
What runs in the background, what consumes storage, and the values in one place.
When InfoIQ catches an error it writes twice: a payload to the debug log,
and a platform event that a trigger turns into an
Announcement_Log__c row. The event is published immediately
rather than after commit, because almost every error is caught inside a
transaction that is about to roll back — a row inserted there would roll
back with it, losing precisely the entries worth keeping.
Logging never throws. A logger that failed would turn a handled error into an unhandled one.
| Purge | Runs |
|---|---|
| Entries of a deleted announcement | Automatically, as part of the delete |
| Anything older than 30 days | Only if you schedule it — section 5 |
Log rows sit in your data storage. That is why nothing in them records what an announcement said or who read it, and why a logger without a purge would be a leak in somebody else's org.
Deleting an announcement cascades to its pages, rules, questions and reading states. Its figures survive as a snapshot — section 12 — but its contents do not. If the snapshot cannot be written, the deletion is aborted rather than losing the history quietly.
Images, videos and imported decks are Salesforce files. There is no referential integrity between a page and its file — the platform does not allow a lookup to a file — so InfoIQ tracks the link itself and collects what is no longer referenced. It collects at two moments. A save in the builder, or a deck import, removes the page files that no page uses any more. Deleting an announcement removes the files it alone was using, if you tick that option in the Delete dialog.
Not just InfoIQ's: every save, everywhere, fails with an error that rarely names storage as the cause. Decks are the usual culprit — a deck uploaded to an announcement and then abandoned keeps its space until it is collected. Watch file storage the same way you watch data storage.
A file is flagged as page media the moment it is uploaded, not when it is used, because the platform writes the file as soon as the author picks it — before they have said what it is for. Anything not flagged is ignored by the collector, which is what keeps it from touching files that have nothing to do with InfoIQ.
| Field | Values |
|---|---|
| Status | Draft, Published, Unpublished, Archived |
| Priority | Low, Medium, High, Urgent, Critical |
| Announcement type | Bug / Incident, New feature, Scheduled maintenance, Training / Tutorial, Strategic information, Other |
| Targeting mode | Criteria, Audience |
| Logic mode | Any, All, Custom |
| Page type | Text, Image, Video |
| Criterion | Profile, User, Role, Group, Queue, Application, Page type, Custom identifier |
| Operator | In, Not in |
| Question status | New, Answered |
| Reading state | Displayed, Completed, Dismissed |
The bypass permission (section 5) lifts all of them except the two that keep dates in order: an end before its start, and a last publish date before the first.
| Object | Refuses |
|---|---|
| Announcement | Going back to Draft once published |
| Announcement | Publishing without a page |
| Announcement | Publishing without a publish start |
| Announcement | Setting a publish start in the past |
| Announcement | Publishing with a publish end already past |
| Announcement | A publish end before its start |
| Announcement | A last publish date before the first, or without one |
| Announcement | Custom logic with no expression |
| Announcement | Changing the logic mode outside Draft |
| Announcement | Unpublishing something never published |
| Page | Changing content outside Draft |
| Rule | Changing targeting outside Draft |
| Question | Answered without a response |
| Question | Visible on the announcement without a response |
| Question | Skipping an answered question |
| Value | Setting |
|---|---|
| Archive suggested at | 80% coverage |
| Low reach suggested below | 50% coverage, after 7 days live |
| Quiet after raising priority | 2 days |
| Expiry horizon | 3 days |
| Extension applied | 7 days |
| Metrics tab warning below | 50 readings |
| Analytics measure silent below | 50 readings, or 5 announcements per band |
| Middle half drawn from | 10 announcements |
| Half-life horizon | 30 days |
| Log retention | 30 days |
| Object | Holds |
|---|---|
| Announcement | The announcement itself |
| Announcement Page | One page of content |
| Announcement Rule | One targeting criterion on an announcement |
| Announcement Audience | A named reusable audience |
| Announcement Audience Rule | One criterion inside an audience |
| Announcement Audience Link | Ties an audience to an announcement |
| Announcement User State | One reader's reading of one announcement |
| Announcement Page User State | One reader's reading of one page |
| Announcement Question | A question and its answer |
| Announcement Analytics Snapshot | The figures of a deleted announcement |
| Announcement Recommendation Decision | A suggestion dismissed or acted on |
| Announcement Log | A diagnostic entry |