diff --git a/libpurple/purplesavedpresence.h b/libpurple/purplesavedpresence.h
--- a/libpurple/purplesavedpresence.h
+++ b/libpurple/purplesavedpresence.h
@@ -247,6 +247,24 @@
 PURPLE_AVAILABLE_IN_3_0
 gboolean purple_saved_presence_equal(PurpleSavedPresence *a, PurpleSavedPresence *b);
 
+/**
+ * purple_saved_presence_matches:
+ * @presence: The instance.
+ * @needle: (nullable): The string to match on.
+ *
+ * Checks if @needle matches the [property@SavedPresence:name],
+ * [property@SavedPresence:message], or [property@SavedPresence:emoji] of
+ * @presence.
+ *
+ * If @needle is %NULL or empty string, %TRUE will be returned.
+ *
+ * Returns: %TRUE if @presence matches @needle in any way, otherwise %FALSE.
+ *
+ * Since: 3.0.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_saved_presence_matches(PurpleSavedPresence *presence, const char *needle);
+
 G_END_DECLS
 
 #endif /* PURPLE_SAVED_PRESENCE_H */
# HG changeset patch
# Node ID 612a16bf41f2
# Parent  0e752027f115
diff --git a/libpurple/purplesavedpresence.c b/libpurple/purplesavedpresence.c
--- a/libpurple/purplesavedpresence.c
+++ b/libpurple/purplesavedpresence.c
@@ -634,3 +634,28 @@
 
 	return TRUE;
 }
+
+gboolean
+purple_saved_presence_matches(PurpleSavedPresence *presence,
+                              const char *needle)
+{
+	g_return_val_if_fail(PURPLE_IS_SAVED_PRESENCE(presence), FALSE);
+
+	if(purple_strempty(needle)) {
+		return TRUE;
+	}
+
+	if(purple_strmatches(needle, presence->name)) {
+		return TRUE;
+	}
+
+	if(purple_strmatches(needle, presence->message)) {
+		return TRUE;
+	}
+
+	if(purple_strequal(needle, presence->emoji)) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
diff --git a/libpurple/tests/test_saved_presence.c b/libpurple/tests/test_saved_presence.c
--- a/libpurple/tests/test_saved_presence.c
+++ b/libpurple/tests/test_saved_presence.c
@@ -400,6 +400,75 @@
 	g_clear_object(&b);
 }
 
+static void
+test_purple_saved_presence_matches_accepts_null(void) {
+	PurpleSavedPresence *presence = NULL;
+
+	presence = g_object_new(PURPLE_TYPE_SAVED_PRESENCE, NULL);
+	g_assert_true(purple_saved_presence_matches(presence, NULL));
+
+	g_assert_finalize_object(presence);
+}
+
+static void
+test_purple_saved_presence_matches_empty_string(void) {
+	PurpleSavedPresence *presence = NULL;
+
+	presence = g_object_new(PURPLE_TYPE_SAVED_PRESENCE, NULL);
+	g_assert_true(purple_saved_presence_matches(presence, ""));
+
+	g_assert_finalize_object(presence);
+}
+
+static void
+test_purple_saved_presence_matches_name(void) {
+	PurpleSavedPresence *presence = NULL;
+
+	presence = g_object_new(PURPLE_TYPE_SAVED_PRESENCE,
+	                        "name", "getting pidgy with it",
+	                        NULL);
+	g_assert_true(purple_saved_presence_matches(presence, "pidgy"));
+
+	g_assert_finalize_object(presence);
+}
+
+static void
+test_purple_saved_presence_matches_message(void) {
+	PurpleSavedPresence *presence = NULL;
+
+	/* This message came from a Twitch viewer while I was writing this code.
+	 * Previously I typoed purple as purpel and started making jokes with it.
+	 */
+	presence = g_object_new(PURPLE_TYPE_SAVED_PRESENCE,
+	                        "message", "Uro666: purpelling to new heights",
+	                        NULL);
+	g_assert_true(purple_saved_presence_matches(presence, "purpel"));
+
+	g_assert_finalize_object(presence);
+}
+
+static void
+test_purple_saved_presence_matches_emoji(void) {
+	PurpleSavedPresence *presence = NULL;
+
+	presence = g_object_new(PURPLE_TYPE_SAVED_PRESENCE,
+	                        "emoji", "😴",
+	                        NULL);
+	g_assert_true(purple_saved_presence_matches(presence, "😴"));
+
+	g_assert_finalize_object(presence);
+}
+
+static void
+test_purple_saved_presence_matches_none(void) {
+	PurpleSavedPresence *presence = NULL;
+
+	presence = g_object_new(PURPLE_TYPE_SAVED_PRESENCE, NULL);
+	g_assert_false(purple_saved_presence_matches(presence, "away"));
+
+	g_assert_finalize_object(presence);
+}
+
 /******************************************************************************
  * Main
  *****************************************************************************/
@@ -440,5 +509,18 @@
 	g_test_add_func("/saved-presence/equal/emoji",
 	                test_purple_saved_presence_equal_emoji);
 
+	g_test_add_func("/saved-presence/matches/accepts_null",
+	                test_purple_saved_presence_matches_accepts_null);
+	g_test_add_func("/saved-presence/matches/empty_string",
+	                test_purple_saved_presence_matches_empty_string);
+	g_test_add_func("/saved-presence/matches/name",
+	                test_purple_saved_presence_matches_name);
+	g_test_add_func("/saved-presence/matches/message",
+	                test_purple_saved_presence_matches_message);
+	g_test_add_func("/saved-presence/matches/emoji",
+	                test_purple_saved_presence_matches_emoji);
+	g_test_add_func("/saved-presence/matches/none",
+	                test_purple_saved_presence_matches_none);
+
 	return g_test_run();
 }
