Making WordPress.org


Ignore:
Timestamp:
06/29/2022 09:38:19 PM (3 years ago)
Author:
iandunn
Message:

Profiles: Include links in Slack props messages.

Previously they were unintentionally stripped out, because Slack escapes them in brackets, like <http://example.org>. That caused them to get stripped out by handle_props_given() in wporg-profiles-activity-handler.php.

For example, https://wordpress.slack.com/archives/C0FRG66LR/p1655471187798639.

This refactors prepare_message() to use the structured message blocks, rather than the concatenated text. That makes it easier to un-escape each part of the message according to its type.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/common/includes/slack/props/lib.php

    r11789 r11927  
    4646    // This is Slack's unintuitive way of giving messages a unique ID :|
    4747    // https://api.slack.com/messaging/retrieving#individual_messages
    48     $message_id = sprintf( '%s-%s', $request->event->channel, $request->event->ts );
    49     $message    = prepare_message( $request->event->text, $recipient_users );
     48    $message_id    = sprintf( '%s-%s', $request->event->channel, $request->event->ts );
     49    $channel_names = map_slack_channel_ids_to_names( $request->event->text );
     50    $message       = prepare_message( $request->event->blocks[0]->elements[0]->elements, $recipient_users, $channel_names );
    5051
    5152    add_activity_to_profile( compact( 'giver_user', 'recipient_ids', 'url', 'message_id', 'message' ) );
     
    143144
    144145/**
     146 * Parse Slack channel names and IDs out of message.
     147 *
     148 * This avoids having to make an API call to Slack to fetch the channels, like their docs recommend.
     149 */
     150function map_slack_channel_ids_to_names( string $message ) : array {
     151    $map = array();
     152
     153    preg_match_all( '/<#(\w*\d*)\|([\w-]*)>/m', $message, $matches, PREG_SET_ORDER );
     154
     155    foreach ( $matches as $match ) {
     156        $map[ $match[1] ] = $match[2];
     157    }
     158
     159    return $map;
     160}
     161
     162
     163/**
     164 * Prepare message to be sent to the Profiles API.
     165 *
    145166 * Replace Slack IDs with w.org usernames, to better fit w.org profiles.
    146  */
    147 function prepare_message( string $original, array $user_map ) : string {
    148     $search  = array();
    149     $replace = array();
    150 
    151     foreach ( $user_map as $slack_id => $wporg_user ) {
    152         $search[]  = sprintf( '<@%s>', $slack_id );
    153         $replace[] = '@' . $wporg_user['user_login'];
    154     }
    155 
    156     return str_replace( $search, $replace, $original );
     167 * Un-escape URLs and other things Slack has escaped.
     168 */
     169function prepare_message( array $elements, array $user_map, array $channel_map ) : string {
     170    $prepared = '';
     171
     172    foreach ( $elements as $element ) {
     173        switch ( $element->type ) {
     174            case 'text':
     175                $prepared .= $element->text;
     176            break;
     177
     178            case 'link':
     179                $prepared .= $element->url;
     180            break;
     181
     182            case 'emoji':
     183                $prepared .= ":{$element->name}:";
     184            break;
     185
     186            case 'user':
     187                $prepared .= '@' . $user_map[ $element->user_id ]['user_login'];
     188            break;
     189
     190            case 'channel':
     191                $prepared .= '#' . $channel_map[ $element->channel_id ];
     192            break;
     193
     194            default:
     195                // Ignore
     196            break;
     197        }
     198    }
     199
     200    return $prepared;
    157201}
    158202
Note: See TracChangeset for help on using the changeset viewer.