+/**
+ * Follow a fediverse account that is proived in the name or the profile
+ *
+ * @param integer $uid
+ * @param object $data
+ */
+function twitter_auto_follow(int $uid, object $data)
+{
+ $addrpattern = '([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6})';
+
+ // Search for user@domain.tld in the name
+ if (preg_match('#' . $addrpattern . '#', $data->name, $match)) {
+ if (twitter_add_contact($match[1], true, $uid)) {
+ return;
+ }
+ }
+
+ // Search for @user@domain.tld in the description
+ if (preg_match('#@' . $addrpattern . '#', $data->description, $match)) {
+ if (twitter_add_contact($match[1], true, $uid)) {
+ return;
+ }
+ }
+
+ // Search for user@domain.tld in the description
+ // We don't probe here, since this could be a mail address
+ if (preg_match('#' . $addrpattern . '#', $data->description, $match)) {
+ if (twitter_add_contact($match[1], false, $uid)) {
+ return;
+ }
+ }
+
+ // Search for profile links in the description
+ foreach ($data->entities->description->urls as $url) {
+ if (!empty($url->expanded_url)) {
+ // We only probe on Mastodon style URL to reduce the number of unsuccessful probes
+ twitter_add_contact($url->expanded_url, strpos($url->expanded_url, '@'), $uid);
+ }
+ }
+}
+
+/**
+ * Check if the provided address is a fediverse account and adds it
+ *
+ * @param string $addr
+ * @param boolean $probe
+ * @param integer $uid
+ * @return boolean
+ */
+function twitter_add_contact(string $addr, bool $probe, int $uid): bool
+{
+ $contact = Contact::getByURL($addr, $probe ? null : false, ['id', 'url', 'network']);
+ if (empty($contact)) {
+ Logger::debug('Not a contact address', ['uid' => $uid, 'probe' => $probe, 'addr' => $addr]);
+ return false;
+ }
+
+ if (!in_array($contact['network'], Protocol::FEDERATED)) {
+ Logger::debug('Not a federated network', ['uid' => $uid, 'addr' => $addr, 'contact' => $contact]);
+ return false;
+ }
+
+ if (Contact::isSharing($contact['id'], $uid)) {
+ Logger::debug('Contact has already been added', ['uid' => $uid, 'addr' => $addr, 'contact' => $contact]);
+ return true;
+ }
+
+ Logger::info('Add contact', ['uid' => $uid, 'addr' => $addr, 'contact' => $contact]);
+ Worker::add(Worker::PRIORITY_LOW, 'AddContact', $uid, $contact['url']);
+
+ return true;
+}
+