Blog / Guia para desenvolvedores
Como interpretar e padronizar URLs de perfis de redes sociais (Instagram, TikTok, YouTube, X)
Os criadores colam os links de perfil em todos os formatos imagináveis: com e sem www, vindos do app com parâmetros de rastreamento, como links curtos, como URLs antigas do twitter.com ou como link para um post em vez do perfil. Se o seu produto guarda esses textos do jeito que chegam, o mesmo criador aparece três vezes e seus cruzamentos falham sem aviso. Este guia mostra como transformar qualquer URL de perfil do Instagram, TikTok, YouTube ou X em uma plataforma, um nome de usuário ou ID de canal e uma URL canônica, com código testado em JavaScript e Python.
Por que padronizar URLs de perfil importa
Uma URL de perfil é um identificador, e identificadores só funcionam quando são escritos de um único jeito. https://www.instagram.com/natgeo/, instagram.com/NatGeo?igsh=MWQ1ZGUxMzBkMA== e https://m.instagram.com/natgeo apontam todos para a mesma conta, mas como texto são três valores diferentes.
- Remoção de duplicatas. Quando um criador se cadastra duas vezes, ou duas pessoas da equipe adicionam o mesmo influenciador a uma campanha, você quer um registro, não dois.
- Cruzamentos (joins). Cruzar seu CRM com uma exportação de outra ferramenta só funciona se os dois lados usarem a mesma chave.
- Rejeitar entradas ruins cedo. Um link para um reel, uma página de busca ou uma tela de login não é um perfil. Pegar isso na entrada sai mais barato do que limpar depois.
- Chamar APIs. As APIs oficiais querem um nome de usuário ou um ID, não uma URL com parâmetros de rastreamento.
O objetivo é uma função pequena e rigorosa: aceita o que os usuários realmente colam, retorna um resultado padronizado para URLs de perfil reais e retorna null para todo o resto.
Os formatos de URL que você vai encontrar
Os formatos abaixo foram conferidos nos sites ao vivo em outubro de 2026. As plataformas mudam suas rotas sem aviso, então trate isto como um retrato do momento e mantenha seus casos de teste atualizados.
- Os perfis ficam em
https://www.instagram.com/<handle>/. Os hostsinstagram.com(sem www) em.instagram.comredirecionam parawww.instagram.com. - Links compartilhados pelo app muitas vezes trazem um parâmetro
?igsh=. Descarte a query string inteira e o fragmento. - Posts são
/p/<code>/, reels são/reel/<code>/e stories são/stories/<handle>/<id>/. Nenhum deles é URL de perfil, mesmo quando o nome de usuário aparece no caminho. - Rotas do app como
/explore/,/accounts/e/direct/ocupam o primeiro segmento do caminho, igual aos nomes de usuário, então você precisa de uma lista de palavras reservadas. A lista no código abaixo não é completa.
TikTok
- Os perfis são
https://www.tiktok.com/@<handle>. O hosttiktok.comsem www redireciona parawww. - Vídeos são
/@<handle>/video/<id>. O nome de usuário é o do autor, mas a URL é de um vídeo, então o parser abaixo a rejeita. - Links curtos em
vm.tiktok.com,vt.tiktok.comewww.tiktok.com/t/<code>/não trazem nome de usuário nenhum. Você precisa seguir o redirecionamento HTTP para ver aonde levam e depois interpretar a URL final. - Um caminho sem
@(por exemplotiktok.com/khaby.lame) não é URL de perfil.
YouTube
- URLs de identificador:
https://www.youtube.com/@<handle>. A Central de Ajuda do YouTube diz que o identificador vira automaticamente a URL do canal. - URLs de ID do canal:
https://www.youtube.com/channel/UC.... Esta é a forma estável. Na prática, os IDs de canal têm 24 caracteres e começam comUC. O Google não documenta o formato, então a checagem abaixo é um limite de sanidade, não uma regra. - Formas antigas:
/user/<username>e/c/<customname>. As duas ainda funcionam hoje, e a Central de Ajuda diz que os URLs personalizados antigos continuam funcionando. Nenhuma delas informa o ID do canal sem uma consulta. - Um
youtube.com/<name>simples também ainda funciona para alguns canais, mas divide o espaço de nomes com as rotas do site, então o parser abaixo não o aceita. - Abas como
/@handle/videose/channel/UC.../featuredpertencem ao canal e podem ser aceitas com segurança. m.youtube.comredireciona parawww.youtube.com. Links de vídeo (/watch?v=,/shorts/,youtu.be/<id>) não são canais.
X (antigo Twitter)
- Os perfis são
https://x.com/<handle>.twitter.com,www.twitter.com,www.x.com,mobile.twitter.comemobile.x.comredirecionam todos para um perfil emx.comoutwitter.com, então trate-os como uma única plataforma. - Posts são
/<handle>/status/<id>. Como os vídeos do TikTok, eles indicam o autor, mas não são URLs de perfil. - Rotas do app como
/home,/explore,/search,/settings,/notifications,/messagese qualquer coisa em/i/não são nomes de usuário. - Links compartilhados muitas vezes acrescentam os parâmetros
?s=e?t=. Descarte-os.
Regras de caracteres do nome de usuário por plataforma
Validar o nome de usuário pega erros de digitação e a maioria dos caminhos que não são perfis. Use as regras das próprias plataformas quando elas as publicam e deixe as checagens flexíveis quando não publicam, para nunca rejeitar uma conta real.
| Plataforma | Caracteres permitidos | Tamanho | Maiúsculas e minúsculas | Fonte |
|---|---|---|---|---|
| Letras, números, pontos, sublinhados | 30 é muito citado; não encontrado nas páginas de ajuda do Instagram | Trate como indiferente a maiúsculas; guarde em minúsculas | A Central de Ajuda do Instagram menciona pontos, números e sublinhados | |
| TikTok | Letras, números, sublinhados, pontos; não pode terminar com ponto | 2 a 24 | Indiferente a maiúsculas nas URLs (@TikTok leva a tiktok) | Suporte do TikTok, alteração do nome de usuário |
| YouTube | Letras ou números dos idiomas suportados, mais sublinhados, hifens, pontos e pontos médios latinos (não no início nem no fim) | 3 a 30 na maioria dos sistemas de escrita; limites menores para Han, Hangul e alguns outros | Não diferencia maiúsculas | Ajuda do YouTube, diretrizes de identificadores |
| X | Letras, números e sublinhados | Até 15; nomes novos precisam ter mais de 4, mas existem nomes curtos antigos | Não diferencia maiúsculas (x.com/JACK vira x.com/jack) | Central de Ajuda do X, regras de nome de usuário |
Um algoritmo de padronização
- Step 1Limpe e adicione um esquema
Remova espaços e sinais de menor e maior soltos. Se a entrada não tiver esquema, acrescente
https://no início para queinstagram.com/natgeopossa ser interpretado. - Step 2Use um parser de URL de verdade
Use
new URL()em JavaScript ouurllib.parse.urlsplitem Python, nunca uma regex sobre o texto inteiro. Um parser lida com portas, dados de usuário e caracteres codificados, e impede quehttps://instagram.com@evil.com/natgeopasse como Instagram. - Step 3Padronize o host
Passe para minúsculas e remova um
www.,m.oumobile.do início. Depois procure o host numa lista exata de hosts permitidos. Nunca useincludes("instagram.com"), que também aceitainstagram.com.evil.com. - Step 4Descarte a query string e o fragmento
Parâmetros de rastreamento como
igsh,s,telangnunca mudam o perfil para o qual a URL aponta. - Step 5Divida e decodifique o caminho
Divida em
/, descarte os segmentos vazios (isso remove as barras finais) e aplique a decodificação percentual em cada um. Trate codificação malformada como entrada inválida. - Step 6Encaminhe por plataforma
Aplique o formato de cada plataforma: um segmento no Instagram e no X, um segmento com
@no TikTok e@handle,channel/UC...,user/nameouc/nameno YouTube. Rejeite palavras reservadas. - Step 7Valide e passe o nome para minúsculas
Confira o nome de usuário com as regras de caracteres da plataforma e depois passe para minúsculas. Não passe IDs de canal do YouTube para minúsculas: eles diferenciam maiúsculas.
- Step 8Monte a URL canônica
Reconstrua a URL a partir das partes, num host fixo, para que toda entrada equivalente produza exatamente o mesmo texto.
- Step 9Trate links curtos à parte
Detecte links curtos do TikTok, siga o redirecionamento com uma requisição HTTP e passe a URL final de novo pelo parser. Deixe isso fora da função pura, para que a interpretação continue rápida e testável.
O código em JavaScript e Python
As duas funções retornam os mesmos objetos para a mesma entrada: { platform, handle, canonicalUrl } para URLs com nome de usuário, { platform, channelId, canonicalUrl } para IDs de canal do YouTube, username ou customName para as duas formas antigas do YouTube e null para qualquer coisa que não seja URL de perfil. Nenhuma precisa de dependência.
JavaScript (Node 18+)
const HOSTS = {
"instagram.com": "instagram",
"tiktok.com": "tiktok",
"youtube.com": "youtube",
"x.com": "x",
"twitter.com": "x",
};
const IG_RESERVED = new Set(["p", "reel", "reels", "tv", "stories", "explore", "accounts", "direct"]);
const X_RESERVED = new Set([
"home", "explore", "search", "i", "settings", "notifications", "messages",
"compose", "intent", "hashtag", "login", "signup", "logout", "tos", "privacy",
]);
const IG_HANDLE = /^[a-z0-9._]{1,30}$/;
const TIKTOK_HANDLE = /^[a-z0-9._]{2,24}$/;
const X_HANDLE = /^[a-z0-9_]{1,15}$/;
const YT_HANDLE = /^[\p{L}\p{M}\p{N}._\-·]{1,30}$/u;
const YT_CHANNEL_ID = /^UC[A-Za-z0-9_-]{22}$/;
const YT_LEGACY_NAME = /^[A-Za-z0-9._-]{1,100}$/;
export function parseProfileUrl(input) {
if (typeof input !== "string") return null;
let raw = input.trim().replace(/^<|>$/g, "");
if (!raw) return null;
if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(raw)) raw = "https://" + raw;
let url;
try {
url = new URL(raw);
} catch {
return null;
}
if (url.protocol !== "https:" && url.protocol !== "http:") return null;
const host = url.hostname.toLowerCase().replace(/^(www|m|mobile)\./, "");
const platform = HOSTS[host];
if (!platform) return null;
let segments;
try {
segments = url.pathname.split("/").filter(Boolean).map(decodeURIComponent);
} catch {
return null; // malformed percent-encoding
}
const [first = "", second] = segments;
if (platform === "instagram") {
const handle = first.toLowerCase();
if (segments.length !== 1 || IG_RESERVED.has(handle) || !IG_HANDLE.test(handle)) return null;
return { platform, handle, canonicalUrl: `https://www.instagram.com/${handle}/` };
}
if (platform === "tiktok") {
if (segments.length !== 1 || !first.startsWith("@")) return null;
const handle = first.slice(1).toLowerCase();
if (!TIKTOK_HANDLE.test(handle) || handle.endsWith(".")) return null;
return { platform, handle, canonicalUrl: `https://www.tiktok.com/@${handle}` };
}
if (platform === "x") {
const handle = first.toLowerCase();
if (segments.length !== 1 || X_RESERVED.has(handle) || !X_HANDLE.test(handle)) return null;
return { platform, handle, canonicalUrl: `https://x.com/${handle}` };
}
// YouTube: /@handle[/tab], /channel/UC...[/tab], /user/name, /c/name
if (first.startsWith("@")) {
const handle = first.slice(1).toLowerCase();
if (!YT_HANDLE.test(handle) || /^[._\-·]|[._\-·]$/.test(handle)) return null;
return { platform, handle, canonicalUrl: `https://www.youtube.com/@${encodeURIComponent(handle)}` };
}
if (first === "channel" && second && YT_CHANNEL_ID.test(second)) {
return { platform, channelId: second, canonicalUrl: `https://www.youtube.com/channel/${second}` };
}
if ((first === "user" || first === "c") && second && segments.length === 2 && YT_LEGACY_NAME.test(second)) {
const key = first === "user" ? "username" : "customName";
return { platform, [key]: second, canonicalUrl: `https://www.youtube.com/${first}/${second}` };
}
return null; // videos, shorts, playlists, search and anything else
}
const SHORT_HOSTS = new Set(["vm.tiktok.com", "vt.tiktok.com"]);
export function isShortLink(input) {
try {
const url = new URL(/^https?:\/\//i.test(input) ? input : "https://" + input);
const host = url.hostname.toLowerCase();
return SHORT_HOSTS.has(host) || (host.replace(/^www\./, "") === "tiktok.com" && url.pathname.startsWith("/t/"));
} catch {
return false;
}
}
export async function resolveShortLink(input) {
const res = await fetch(/^https?:\/\//i.test(input) ? input : "https://" + input, {
redirect: "follow",
signal: AbortSignal.timeout(10_000),
});
await res.body?.cancel();
return res.url; // the final URL after every redirect
}resolveShortLink usa o fetch nativo, que segue redirecionamentos e expõe o endereço final em res.url. Chame parseProfileUrl(await resolveShortLink(link)) quando isShortLink(link) for verdadeiro. Um link curto também pode levar a um vídeo em vez de um perfil, e nesse caso o parser retorna null, como deve.
Python 3
import re
import unicodedata
import urllib.request
from urllib.parse import quote, unquote, urlsplit
HOSTS = {
"instagram.com": "instagram",
"tiktok.com": "tiktok",
"youtube.com": "youtube",
"x.com": "x",
"twitter.com": "x",
}
IG_RESERVED = {"p", "reel", "reels", "tv", "stories", "explore", "accounts", "direct"}
X_RESERVED = {
"home", "explore", "search", "i", "settings", "notifications", "messages",
"compose", "intent", "hashtag", "login", "signup", "logout", "tos", "privacy",
}
IG_HANDLE = re.compile(r"[a-z0-9._]{1,30}")
TIKTOK_HANDLE = re.compile(r"[a-z0-9._]{2,24}")
X_HANDLE = re.compile(r"[a-z0-9_]{1,15}")
YT_CHANNEL_ID = re.compile(r"UC[A-Za-z0-9_-]{22}")
YT_LEGACY_NAME = re.compile(r"[A-Za-z0-9._-]{1,100}")
YT_PUNCT = "._-·"
def _is_youtube_handle(handle):
if not 1 <= len(handle) <= 30 or handle[0] in YT_PUNCT or handle[-1] in YT_PUNCT:
return False
return all(
ch.isalnum() or ch in YT_PUNCT or unicodedata.category(ch).startswith("M")
for ch in handle
)
def parse_profile_url(value):
if not isinstance(value, str):
return None
raw = value.strip().strip("<>")
if not raw:
return None
if not re.match(r"^[a-z][a-z0-9+.-]*://", raw, re.I):
raw = "https://" + raw
try:
url = urlsplit(raw)
host = (url.hostname or "").lower()
except ValueError:
return None
if url.scheme.lower() not in ("http", "https"):
return None
host = re.sub(r"^(www|m|mobile)\.", "", host)
platform = HOSTS.get(host)
if not platform:
return None
try:
segments = [unquote(s, errors="strict") for s in url.path.split("/") if s]
except UnicodeDecodeError:
return None # malformed percent-encoding
first = segments[0] if segments else ""
second = segments[1] if len(segments) > 1 else None
if platform == "instagram":
handle = first.lower()
if len(segments) != 1 or handle in IG_RESERVED or not IG_HANDLE.fullmatch(handle):
return None
return {"platform": platform, "handle": handle,
"canonicalUrl": f"https://www.instagram.com/{handle}/"}
if platform == "tiktok":
if len(segments) != 1 or not first.startswith("@"):
return None
handle = first[1:].lower()
if not TIKTOK_HANDLE.fullmatch(handle) or handle.endswith("."):
return None
return {"platform": platform, "handle": handle,
"canonicalUrl": f"https://www.tiktok.com/@{handle}"}
if platform == "x":
handle = first.lower()
if len(segments) != 1 or handle in X_RESERVED or not X_HANDLE.fullmatch(handle):
return None
return {"platform": platform, "handle": handle, "canonicalUrl": f"https://x.com/{handle}"}
# YouTube: /@handle[/tab], /channel/UC...[/tab], /user/name, /c/name
if first.startswith("@"):
handle = first[1:].lower()
if not _is_youtube_handle(handle):
return None
return {"platform": platform, "handle": handle,
"canonicalUrl": f"https://www.youtube.com/@{quote(handle, safe='._-')}"}
if first == "channel" and second and YT_CHANNEL_ID.fullmatch(second):
return {"platform": platform, "channelId": second,
"canonicalUrl": f"https://www.youtube.com/channel/{second}"}
if first in ("user", "c") and second and len(segments) == 2 and YT_LEGACY_NAME.fullmatch(second):
key = "username" if first == "user" else "customName"
return {"platform": platform, key: second,
"canonicalUrl": f"https://www.youtube.com/{first}/{second}"}
return None # videos, shorts, playlists, search and anything else
SHORT_HOSTS = {"vm.tiktok.com", "vt.tiktok.com"}
def is_short_link(value):
url = urlsplit(value if re.match(r"^https?://", value, re.I) else "https://" + value)
host = (url.hostname or "").lower()
return host in SHORT_HOSTS or (
re.sub(r"^www\.", "", host) == "tiktok.com" and url.path.startswith("/t/")
)
def resolve_short_link(value, timeout=10):
if not re.match(r"^https?://", value, re.I):
value = "https://" + value
request = urllib.request.Request(value, headers={"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(request, timeout=timeout) as response:
return response.geturl() # the final URL after every redirectEm Python, \w e str.isalnum() cobrem letras e dígitos Unicode, mas não as marcas combinantes usadas por sistemas de escrita como o devanágari, e é por isso que a checagem do YouTube também aceita caracteres das categorias Unicode M.
Casos extremos e testes
Cada linha abaixo faz parte da suíte de testes em que as duas implementações passam.
| Entrada | Saída | Por quê |
|---|---|---|
instagram.com/NatGeo?igsh=MWQ1ZGUxMzBkMA== | instagram, natgeo, https://www.instagram.com/natgeo/ | Sem esquema, maiúsculas misturadas, parâmetro de compartilhamento |
https://m.instagram.com/nat.geo_/#bio | instagram, nat.geo_ | Host mobile e fragmento |
https://www.instagram.com/p/C9xYzAbCdEf/ | null | Um post, não um perfil |
https://www.instagram.com/stories/natgeo/1234567890/ | null | Um story, mesmo com o nome de usuário no caminho |
tiktok.com/@Khaby.Lame/ | tiktok, khaby.lame, https://www.tiktok.com/@khaby.lame | Barra final e maiúsculas |
https://www.tiktok.com/@khaby.lame/video/7106594312292453675 | null | Uma URL de vídeo |
https://vm.tiktok.com/ZMabc123/ | null (siga o redirecionamento antes) | Link curto sem nome de usuário |
https://m.youtube.com/@GoogleDevelopers/videos?app=desktop | youtube, googledevelopers | Host mobile, aba do canal, query |
https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw/featured | youtube, channelId UC_x5XG1OV2P6uZZ5FSM9Ttw | O ID do canal mantém as maiúsculas |
https://www.youtube.com/c/GoogleDevelopers | youtube, customName GoogleDevelopers | URL personalizado antigo; precisa de uma consulta para obter o ID |
https://www.youtube.com/@%E3%83%86%E3%82%B9%E3%83%88 | youtube, handle テスト | Identificador Unicode com codificação percentual |
https://youtu.be/dQw4w9WgXcQ | null | Um vídeo, não um canal |
https://mobile.twitter.com/jack?s=21&t=abc | x, jack, https://x.com/jack | Domínio antigo e parâmetros de compartilhamento |
https://x.com/i/flow/login | null | Rota do app |
https://x.com/this_handle_is_too_long | null | Mais de 15 caracteres |
https://instagram.com.evil.com/natgeo | null | Host imitador |
https://instagram.com@evil.com/natgeo | null | Truque com dados de usuário; o host real é evil.com |
@natgeo | null | Um nome de usuário solto não tem plataforma |
Mantenha os casos no seu repositório e rode-os na CI. Quando uma plataforma adicionar uma rota ou um parâmetro de compartilhamento, você acrescenta uma linha e a correção fica óbvia.
import assert from "node:assert/strict";
import { parseProfileUrl } from "./parse.mjs";
const cases = [
["instagram.com/NatGeo?igsh=MWQ1ZGUxMzBkMA==", { platform: "instagram", handle: "natgeo", canonicalUrl: "https://www.instagram.com/natgeo/" }],
["https://www.instagram.com/reel/C9xYzAbCdEf/", null],
["https://www.instagram.com/explore/", null],
["tiktok.com/@Khaby.Lame/", { platform: "tiktok", handle: "khaby.lame", canonicalUrl: "https://www.tiktok.com/@khaby.lame" }],
["https://www.tiktok.com/@khaby.lame/video/7106594312292453675", null],
["https://vm.tiktok.com/ZMabc123/", null],
["https://m.youtube.com/@GoogleDevelopers/videos", { platform: "youtube", handle: "googledevelopers", canonicalUrl: "https://www.youtube.com/@googledevelopers" }],
["https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw/featured", { platform: "youtube", channelId: "UC_x5XG1OV2P6uZZ5FSM9Ttw", canonicalUrl: "https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw" }],
["https://www.youtube.com/user/GoogleDevelopers", { platform: "youtube", username: "GoogleDevelopers", canonicalUrl: "https://www.youtube.com/user/GoogleDevelopers" }],
["https://youtu.be/dQw4w9WgXcQ", null],
["https://twitter.com/Jack/", { platform: "x", handle: "jack", canonicalUrl: "https://x.com/jack" }],
["https://mobile.twitter.com/jack?s=21", { platform: "x", handle: "jack", canonicalUrl: "https://x.com/jack" }],
["https://x.com/jack/status/20", null],
["https://x.com/i/flow/login", null],
["https://instagram.com.evil.com/natgeo", null],
];
for (const [input, expected] of cases) {
assert.deepEqual(parseProfileUrl(input), expected, input);
}
console.log(`${cases.length} cases passed`);from parse_profile import parse_profile_url
CASES = [
("instagram.com/NatGeo?igsh=MWQ1ZGUxMzBkMA==", {"platform": "instagram", "handle": "natgeo", "canonicalUrl": "https://www.instagram.com/natgeo/"}),
("https://www.instagram.com/reel/C9xYzAbCdEf/", None),
("tiktok.com/@Khaby.Lame/", {"platform": "tiktok", "handle": "khaby.lame", "canonicalUrl": "https://www.tiktok.com/@khaby.lame"}),
("https://vm.tiktok.com/ZMabc123/", None),
("https://m.youtube.com/@GoogleDevelopers/videos", {"platform": "youtube", "handle": "googledevelopers", "canonicalUrl": "https://www.youtube.com/@googledevelopers"}),
("https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw/featured", {"platform": "youtube", "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw", "canonicalUrl": "https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw"}),
("https://youtu.be/dQw4w9WgXcQ", None),
("https://twitter.com/Jack/", {"platform": "x", "handle": "jack", "canonicalUrl": "https://x.com/jack"}),
("https://x.com/i/flow/login", None),
("https://instagram.com.evil.com/natgeo", None),
]
for value, expected in CASES:
assert parse_profile_url(value) == expected, value
print(f"{len(CASES)} cases passed")Guarde a entrada bruta e a forma canônica
A padronização perde informação de propósito, e suas regras vão melhorar com o tempo. Guarde os dois valores:
- `raw_url`: exatamente o que o usuário ou a importação forneceu. Permite rodar um parser melhor depois, e é o que você mostra de volta ao usuário quando ele edita o perfil.
- `platform` e `handle` ou `channel_id`: as partes, com um índice único em
(platform, handle). Esta é a sua chave para remover duplicatas e fazer cruzamentos. - `canonical_url`: a URL reconstruída, para exibição e para chamar a plataforma.
- `parsed_at` e uma versão do parser: para encontrar linhas padronizadas por uma versão antiga das suas regras.
Nomes de usuário não são permanentes. Criadores renomeiam contas em todas as plataformas, e um nome que você guardou no ano passado pode hoje ser de outra pessoa. Quando uma API oficial fornece um ID estável, como o ID de canal do YouTube, guarde-o como chave de longo prazo e trate o nome de usuário como um valor de exibição que você atualiza. O guia complementar sobre como obter o ID de um canal do YouTube a partir do identificador mostra como.
De um perfil para os outros
Depois que uma URL de perfil está padronizada, a próxima pergunta costuma ser quais outras contas pertencem ao mesmo criador. O sociallinks.dev é uma API que recebe a URL de um perfil do Instagram, TikTok, YouTube ou X e retorna as contas do criador em outras plataformas, com uma pontuação de confiança e as evidências de cada correspondência.
Perguntas frequentes
Devo passar os nomes de usuário para minúsculas antes de guardar?
Sim, para a chave de busca. O YouTube e o X dizem que os nomes de usuário não diferenciam maiúsculas, e o TikTok leva @TikTok à mesma conta que @tiktok. O Instagram não documenta uma regra, mas os nomes de usuário são exibidos em minúsculas, então usar minúsculas é o padrão seguro. Mantenha a grafia original na URL bruta se quiser exibi-la. Não passe IDs de canal do YouTube para minúsculas, porque eles diferenciam maiúsculas.
Dá para extrair o nome de usuário de uma URL de post ou vídeo?
Em vídeos do TikTok (/@handle/video/id) e posts do X (/handle/status/id), o nome de usuário no caminho é o do autor, então você pode extraí-lo se for isso que quer. URLs de posts e reels do Instagram (/p/ e /reel/) não incluem o nome de usuário. As funções deste guia retornam null para todas elas porque não são links de perfil.
Como lidar com links vm.tiktok.com?
Links curtos contêm só um código. Faça uma requisição HTTP, siga os redirecionamentos e interprete a URL final. Faça isso numa etapa separada, com timeout e cache, porque é uma chamada de rede e o código pode expirar.
twitter.com ainda é uma URL de perfil válida?
Sim. URLs de perfil do twitter.com redirecionam para o x.com, então trate os dois domínios como a plataforma X e guarde a forma x.com como canônica.
Por que não usar uma única expressão regular grande?
Uma única regex sobre o texto inteiro é difícil de ler e fácil de enganar com hosts imitadores, dados de usuário ou caracteres codificados. Interprete a URL primeiro com a biblioteca padrão e depois use regexes pequenas só no nome de usuário.
Como transformar uma URL /c/ ou /user/ do YouTube em ID do canal?
URLs /user/<name> correspondem ao filtro forUsername da YouTube Data API. Não existe filtro na API para nomes personalizados /c/. Veja o guia sobre como obter o ID de um canal do YouTube a partir do identificador para os dois casos.