Page MenuHomePhabricator

Channel QA
Open, MediumPublic

Description

@JMando spotted that the channel for these 2 donations should be Wikipedia App not Direct_Mail

131494427

131495469

For the first contribution tracking is

"contribution_id": 131494427,
"amount": 3.3500000000000001,
"currency": "USD",
"usd_amount": null,
"is_recurring": false,
"referrer": null,
"utm_medium": "WikipediaApp",
"utm_campaign": "Android",
"utm_key": null,
"gateway": "adyen",
"appeal": null,
"payments_form_variant": null,
"banner": "enUS_appmenu_Android",
"landing_page": "inapp",
"payment_method_id": 243,
"payment_submethod_id": 273,
"language": "en",
"country": "US",
"tracking_date": "2025-10-09 21:18:47",
"os": "Android",
"os_version": null,
"browser": "app",
"browser_version": "2.7.50550-r-2025-09-22",
"recurring_choice_id": null,
"device_type_id": null,
"banner_size_id": 3,
"is_test_variant": true,
"banner_variant": "appmenu",
"is_pay_fee": null,
"mailing_identifier": null,
"utm_source": "enUS_appmenu_Android.inapp.google",

The code appears correct so I'm not sure where it's happening....

public function getChannel(): string {
   if (!empty($this->message['Gift_Data.Channel'])) {
     return (string) $this->message['Gift_Data.Channel'];
   }
   if (!empty($this->message['channel'])) {
     return $this->message['channel'];
   }
   if ($this->isSubsequentRecurring()) {
     // The first recurring goes to the solicted channel. After that to Recurring Gift.
     return 'Recurring Gift';
   }
   if (!empty($this->message['recipient_id'])) {
     return 'SMS';
   }
   $utmSource = $this->message['utm_source'] ?? '';
   $utmMedium = strtolower($this->message['utm_medium'] ?? '');

   if ($utmMedium === 'mail' || str_contains('DMURL', $utmSource)) {
     return 'Direct_Mail';
   }

   if ($utmMedium === 'sitenotice'
     // Endowment gifts put endowment in the medium...
     || ($this->isEndowmentGift() && str_starts_with($utmSource, 'B'))
   ) {
     if (str_contains($utmSource, '_m_')
       || str_contains($utmSource, 'mob')
     ) {
       return 'Mobile Banner';
     }
     if (str_contains($utmSource, 'dsk')) {
       return 'Desktop Banner';
     }
     return 'Other Banner';
   }
   // Once the endowment banner check is done let's be case insensitive.
   $utmSource = strtolower($utmSource);
   if ($utmMedium === 'sidebar') {
     return 'Sidebar';
   }

   if (str_starts_with($utmSource, 'sp') || $utmMedium === 'email') {
     return 'Email';
   }
   if ($utmMedium === 'portal') {
     if (($this->message['utm_campaign'] ?? '') == 'portalBanner') {
       return 'Portal Banner';
     }
     else {
       return 'Other Portal';
     }
   }

   if (in_array($utmMedium, ['wikipediaapp', 'wikipediaappfeed'])) {
     return 'Wikipedia App';
   }

   if (in_array($utmMedium, ['google', 'facebook', 'instagram', 'tiktok', 'threads'])) {
     return 'Social Media';
   }

   return 'Other Online';
 }

Related Objects

Event Timeline

@Eileenmcnaughton Is it because WikipediaApp is capitalized in in the column but not the code? Not sure if medium here is still case sensitive?

@JMando - no it has been strtolower'd earlier on & the return for Direct Mail is earlier on too - my best guess is the data incoming has got something going on....

XenoRyet triaged this task as Medium priority.Oct 14 2025, 7:46 PM

Change #1196163 had a related patch set uploaded (by Lars SG; author: Lars SG):

[wikimedia/fundraising/crm@master] Fix str_contains for getChannel()

https://gerrit.wikimedia.org/r/1196163

Lars subscribed.

@Eileenmcnaughton Is it possible that $this->message['utm_source'] would be null or empty for these two for some reason? That would have resulted in the results above in combination with the backwards str_contains.

Change #1196163 merged by jenkins-bot:

[wikimedia/fundraising/crm@master] Fix str_contains for getChannel()

https://gerrit.wikimedia.org/r/1196163

I think @Lars patch should fix - now deployed. We need to fix up the data too though for the ones that have gone through

There are 420 to correct, all actually app, so easily done, but maybe there is a clue as to what happened in this data. We haven't received one that looks like the incorrect ones below since this was deployed, so not confident this is fixed.

Incorrect DM channel:

select count(c.id), ct.utm_medium, ct.utm_source, gd.channel from civicrm_contribution c
LEFT JOIN civicrm_value_1_gift_data_7 gd on c.id = gd.entity_id
LEFT JOIN civicrm_contribution_tracking ct on c.id = ct.contribution_id
where c.receive_date > 20251006000100 and gd.channel = 'Direct_Mail' AND ct.utm_medium != 'mail'
group by ct.utm_source;

All of these have utm_source with inapp.google or inapp.apple, e.g.
appmenu.inapp.apple, csCZ_appmenu_iOS.inapp.apple, deFR_appmenu_Android.inapp.google

Correct channel:

select count(c.id), ct.utm_medium, ct.utm_source, gd.channel from civicrm_contribution c
LEFT JOIN civicrm_value_1_gift_data_7 gd on c.id = gd.entity_id
LEFT JOIN civicrm_contribution_tracking ct on c.id = ct.contribution_id
where c.receive_date > 20251006000100 and gd.channel = 'Wikipedia App' AND ct.utm_medium != 'mail'
group by ct.utm_source;

These are all app.something, e.g. appmenu.app.rrtbt.sepadirectdebit, enUS_appmenu_iOS.app.rcc, etc. None of them are inapp, all are app.

So my guess is that the inapp ones are missing the source initially somehow. @Eileenmcnaughton does that mean anything to you?
Do we have logs that will help with this? Or should we add some temp logging in here?

We'll also have to clean up a few after the patch above (after 2025-10-14 22:40:00) that are now falling into the default Other Online.

Change #1196202 had a related patch set uploaded (by Cstone; author: Cstone):

[wikimedia/fundraising/crm@master] Native (inapp) donations are losing the utms

https://gerrit.wikimedia.org/r/1196202

Change #1196203 had a related patch set uploaded (by Cstone; author: Cstone):

[mediawiki/extensions/DonationInterface@master] Add test for utm medium and source

https://gerrit.wikimedia.org/r/1196203

Lars removed Lars as the assignee of this task.Oct 15 2025, 5:50 PM

Change #1197740 had a related patch set uploaded (by Cstone; author: Cstone):

[mediawiki/extensions/DonationInterface@master] Send campaign,medium,source, and key to the donations queue

https://gerrit.wikimedia.org/r/1197740

Change #1196203 abandoned by Cstone:

[mediawiki/extensions/DonationInterface@master] Send utms to donations queue

https://gerrit.wikimedia.org/r/1196203

Change #1199336 had a related patch set uploaded (by Ejegg; author: Ejegg):

[mediawiki/extensions/DonationInterface@master] WIP simplify app API createPayment params

https://gerrit.wikimedia.org/r/1199336

One the patch currently in review has gone out I will ask Joseph to review with regards to

  1. are any channels incorrect
  2. can all the remaining channels with contribution_tracking rows be assigned to 'Other Online' - these can be found with the query below. Specific ones I'm less sure about are (by utm_medium)
  • NULL - some of these might be Engage or Benevity since we used to add them. Maybe I can check by Financial Type ID & put to ? Offline Other? for those?
  • email - these don't have mailing_identifier but should probably still be Email
  • the endowment ones have had the utm_source that looks like B* already coded - the rest are online other?
  • the ones that look a bit like Major GIfts & events?

select utm_medium, count(*) FROM civicrm_contribution_tracking a INNER JOIN (civicrm_contribution ContributionTracking_Contribution_contribution_id_01) ON a.contribution_id = ContributionTracking_Contribution_contribution_id_01.id LEFT JOIN civicrm_contact contact_id_1 ON ContributionTracking_Contribution_contribution_id_01.contact_id = contact_id_1.id LEFT JOIN civicrm_contribution contribution_id_2 ON a.contribution_id = contribution_id_2.id LEFT JOIN civicrm_value_1_gift_data_7 Gift_Data_3 ON ContributionTracking_Contribution_contribution_id_01.id = Gift_Data_3.entity_id WHERE (Gift_Data_3.channel = "" OR Gift_Data_3.channel IS NULL) GROUP BY utm_medium;

@Eileenmcnaughton I am able to compare this column to analytic's donation type now in the data lake. See quick summary here: https://docs.google.com/spreadsheets/d/1GVJSFuBB76bAA1mCf2xoTh58fcG9iu_mW33ZGqoh_Ws/edit?gid=0#gid=0

It looks like mostly these match! But I see portions that do not. For example 3,256,135 do not have a channel and I also see 26,779 desktop banner in Mobile Banner. I would like to go through all of these and see if the mismatch is that donation type is wrong or there is something we can add to the channel code to align. I will add comments to the google sheet.

Also, I see two channels for the app, "Wikipedia App" and "WikipediaApp."

Change #1199336 abandoned by Ejegg:

[mediawiki/extensions/DonationInterface@master] WIP simplify app API createPayment params

Reason:

folded into I45993d14e7abafc9334cff8f52245150240448e4

https://gerrit.wikimedia.org/r/1199336

Change #1207234 had a related patch set uploaded (by Eileen; author: Eileen):

[wikimedia/fundraising/crm@master] Look for _dsk_ before mob when considering channel

https://gerrit.wikimedia.org/r/1207234

@JMando I just pushed up https://gerrit.wikimedia.org/r/c/wikimedia/fundraising/crm/+/1207234 to consider _dsk_ before mob

What I'm wondering is whether I should still handle dsk after _dsk_, _m_ and mob - or do we feel that dsk is only historical & _dsk_ is reliable now?

Change #1207234 merged by jenkins-bot:

[wikimedia/fundraising/crm@master] Look for _dsk_ before mob when considering channel

https://gerrit.wikimedia.org/r/1207234

Change #1197740 merged by jenkins-bot:

[mediawiki/extensions/DonationInterface@master] Send campaign, medium, source, and key to the donations queue

https://gerrit.wikimedia.org/r/1197740

Finally got this deployed,

Channel Wikipedia App on my test donation.

Change #1196202 merged by jenkins-bot:

[wikimedia/fundraising/crm@master] Native (inapp) donations are losing the utms

https://gerrit.wikimedia.org/r/1196202