VipBug
Um gateway de SMS: seu site ganha a capacidade de enviar mensagens usando o SIM do seu próprio celular, sem contratar plano de envio. Ótimo para códigos de verificação 2FA, alertas e notificações. Tudo criptografado de ponta a ponta. Não é apropriado para disparo de SMS em massa.
id único do app, o id único e senhas de cada site.Funciona em qualquer linguagem. O código monta a mensagem criptografada
(AES-128-GCM), tenta enviar direto para o celular e se não conseguir pela limitação do ipv6
utiliza o nosso servidor para fazer relay.
Escolha abaixo qual linguagem você usa no seu backend:
<?php
const SMSVIP_PHP = 'https://vipbug.com/smsvip';
const SMSVIP_APP = 'UUID_DO_APP';
const SMSVIP_SITE = 'UUID_DO_SITE';
const SMSVIP_KEY = 'SENHA_DO_SITE'; // 32 hex
function smsvip_send($to, $text) {
$env = smsvip_seal($to, $text);
// 1) tenta direto no celular
$info = @file_get_contents(SMSVIP_PHP.'/resolve.php?app='.urlencode(SMSVIP_APP));
$j = $info ? json_decode($info, true) : null;
if ($j && !empty($j['online']) && !empty($j['url'])) {
$r = smsvip_post($j['url'].'/relay', ['envelope'=>$env], 6);
if ($r !== null) return json_decode($r, true);
}
// 2) fallback: relay
$r = smsvip_post(SMSVIP_PHP.'/relay.php', ['uuid_app'=>SMSVIP_APP,'envelope'=>$env], 25);
return $r !== null ? json_decode($r, true) : ['ok'=>false,'error'=>'sem conexao'];
}
function smsvip_seal($to, $text) {
$key = hex2bin(SMSVIP_KEY);
$plain = json_encode(['to'=>$to,'text'=>$text,'ts'=>time(),'site'=>SMSVIP_SITE]);
$nonce = random_bytes(12); $tag = '';
$ct = openssl_encrypt($plain, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag, '', 16);
return base64_encode($nonce.$ct.$tag);
}
function smsvip_post($url, $data, $timeout) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => 5,
]);
$out = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); curl_close($ch);
return ($out !== false && $code) ? $out : null;
}
// uso:
$r = smsvip_send('+5585999999999', 'Seu codigo: 1234');
echo $r['ok'] ? 'enviado' : ('erro: '.$r['error']);# pip install cryptography
import json, time, os, base64, urllib.request, urllib.parse
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
SMSVIP_PHP = "https://vipbug.com/smsvip"
SMSVIP_APP = "UUID_DO_APP"
SMSVIP_SITE = "UUID_DO_SITE"
SMSVIP_KEY = "SENHA_DO_SITE" # 32 hex
def _seal(to, text):
key = bytes.fromhex(SMSVIP_KEY)
plain = json.dumps({"to": to, "text": text, "ts": int(time.time()), "site": SMSVIP_SITE}).encode()
nonce = os.urandom(12)
ct = AESGCM(key).encrypt(nonce, plain, None) # ciphertext + tag
return base64.b64encode(nonce + ct).decode()
def _get(url, timeout):
with urllib.request.urlopen(url, timeout=timeout) as r:
return json.loads(r.read())
def _post(url, data, timeout):
req = urllib.request.Request(url, data=json.dumps(data).encode(),
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=timeout) as r:
return json.loads(r.read())
def smsvip_send(to, text):
env = _seal(to, text)
try:
info = _get(SMSVIP_PHP + "/resolve.php?app=" + urllib.parse.quote(SMSVIP_APP), 8)
if info.get("online") and info.get("url"):
try:
return _post(info["url"] + "/relay", {"envelope": env}, 6)
except Exception:
pass
except Exception:
pass
return _post(SMSVIP_PHP + "/relay.php", {"uuid_app": SMSVIP_APP, "envelope": env}, 25)
# uso:
print(smsvip_send("+5585999999999", "Seu codigo: 1234"))// Node 18+ (fetch nativo)
const crypto = require('crypto');
const SMSVIP_PHP = 'https://vipbug.com/smsvip';
const SMSVIP_APP = 'UUID_DO_APP';
const SMSVIP_SITE = 'UUID_DO_SITE';
const SMSVIP_KEY = 'SENHA_DO_SITE'; // 32 hex
function seal(to, text) {
const key = Buffer.from(SMSVIP_KEY, 'hex');
const plain = Buffer.from(JSON.stringify({ to, text, ts: Math.floor(Date.now() / 1000), site: SMSVIP_SITE }));
const iv = crypto.randomBytes(12);
const c = crypto.createCipheriv('aes-128-gcm', key, iv);
const ct = Buffer.concat([c.update(plain), c.final()]);
return Buffer.concat([iv, ct, c.getAuthTag()]).toString('base64');
}
async function smsvipSend(to, text) {
const env = seal(to, text);
try {
const info = await (await fetch(`${SMSVIP_PHP}/resolve.php?app=${encodeURIComponent(SMSVIP_APP)}`)).json();
if (info.online && info.url) {
try {
const r = await fetch(`${info.url}/relay`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ envelope: env }), signal: AbortSignal.timeout(6000),
});
return await r.json();
} catch (e) { /* cai no relay */ }
}
} catch (e) { /* cai no relay */ }
const r = await fetch(`${SMSVIP_PHP}/relay.php`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ uuid_app: SMSVIP_APP, envelope: env }),
});
return await r.json();
}
// uso:
smsvipSend('+5585999999999', 'Seu codigo: 1234').then(console.log);import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URI;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.Base64;
public class SmsVip {
static final String PHP = "https://vipbug.com/smsvip";
static final String APP = "UUID_DO_APP";
static final String SITE = "UUID_DO_SITE";
static final String KEY = "SENHA_DO_SITE"; // 32 hex
static final HttpClient HTTP = HttpClient.newHttpClient();
public static String send(String to, String text) throws Exception {
String env = seal(to, text);
try {
String info = get(PHP + "/resolve.php?app=" + APP, 8);
if (info.contains("\"online\":true")) {
String url = extract(info, "\"url\":\"", "\"");
if (url != null) {
try { return post(url + "/relay", "{\"envelope\":\"" + env + "\"}", 6); }
catch (Exception ignore) {}
}
}
} catch (Exception ignore) {}
return post(PHP + "/relay.php", "{\"uuid_app\":\"" + APP + "\",\"envelope\":\"" + env + "\"}", 25);
}
static String seal(String to, String text) throws Exception {
byte[] key = hex(KEY);
long ts = System.currentTimeMillis() / 1000;
String plain = "{\"to\":\"" + esc(to) + "\",\"text\":\"" + esc(text)
+ "\",\"ts\":" + ts + ",\"site\":\"" + SITE + "\"}";
byte[] iv = new byte[12];
new SecureRandom().nextBytes(iv);
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(128, iv));
byte[] ctTag = c.doFinal(plain.getBytes(StandardCharsets.UTF_8));
byte[] env = new byte[12 + ctTag.length];
System.arraycopy(iv, 0, env, 0, 12);
System.arraycopy(ctTag, 0, env, 12, ctTag.length);
return Base64.getEncoder().encodeToString(env);
}
static String get(String url, int sec) throws Exception {
HttpRequest r = HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofSeconds(sec)).GET().build();
return HTTP.send(r, HttpResponse.BodyHandlers.ofString()).body();
}
static String post(String url, String body, int sec) throws Exception {
HttpRequest r = HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofSeconds(sec))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body)).build();
return HTTP.send(r, HttpResponse.BodyHandlers.ofString()).body();
}
static String esc(String s) { return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n"); }
static String extract(String s, String a, String b) {
int i = s.indexOf(a); if (i < 0) return null; i += a.length();
int j = s.indexOf(b, i); return j < 0 ? null : s.substring(i, j);
}
static byte[] hex(String h) {
byte[] o = new byte[h.length() / 2];
for (int i = 0; i < o.length; i++) o[i] = (byte) Integer.parseInt(h.substring(2*i, 2*i+2), 16);
return o;
}
public static void main(String[] a) throws Exception {
System.out.println(send("+5585999999999", "Seu codigo: 1234"));
}
}
1. Copie o código que corresponde à linguagem do site que vai ser implementado.
2. Substitua no código as chaves: "UUID_DO_APP", "UUID_DO_SITE" e "SENHA_DO_SITE" pelos valores que você vê no app.;
3. Chame a função smsvip_send(T,M) ou smsvipsend(T,M) onde T é o número do celular que receberá o SMS e M é a mensagem que você quer enviar.
4. As últimas linhas de cada script é um exemplo de como usar.
Caso tenha alguma dúvida ou queira apenas comentar alguma coisa sobre esse app, Sempre procuro responder!