분류 기타

Twilio를 사용하여 인터넷 구축

컨텐츠 정보

  • 조회 239 (작성일 )

본문

국제적으로 여행 한 적이 있다면 아마도 스스로에게 물었을 것입니다.“고가의 로밍 데이터 요금제를 구입합니까, 무료 Wi-Fi 핫스팟에서 다음으로 이동합니까, 아니면 바람에 주의를 기울이고 연결없이 이동합니까? 낯선 곳에서?”. 나 자신만큼 방향 장애가 있고 직선으로 길을 잃는 경우 실시간 내비게이션없이 어디든 갈 수 없습니다. 나는 항상 1GB에 80 달러를 되돌릴 수 있는 데이터 요금제를 선택해야 합니다. 캐나다 통신 산업의 경쟁 부족으로 인해 데이터 가격이 세계 최고 수준으로 상승하고 있으며,이 추가 여행 비용으로 인해 내가 그것에 대해 무언가를 하기로 결심 한 시점까지 실망했습니다.


https://dev.to/twilio/using-twilio-to-build-the-internet-2cnf 


합리적인 사람이 했던 것처럼, 실제 브라우저의 모양과 느낌을 유지하면서 SMS를 통해 모든 콘텐츠를 전송할 수 있는 휴대폰 용 브라우저를 구축하기로 결정했습니다. 당시 전화 계획에 무제한 SMS가 포함되었으므로 이 앱을 사용하여 어디서나 무제한 인터넷을 이용할 수 있습니다! 나는 이것이 느리고 오래된 학교가 될 것이라고 생각했고, 그래서 나의 새로운 프로젝트 "Dial-Up"이 탄생했습니다.


SMS와 코드를 생각하면 Twilio라고 생각합니다. 몇 년 전, Twilio와 FluidSurveys 사이의 SMS / 음성에 대한 설문 조사에 응답 할 수 있는 통합 기능이 출시되었습니다. 앱). 나는 그것이 매우 시원하다고 생각했고, 결국 내 자신의 비 전통적인 사용 사례에 Twilio의 서비스를 사용하게 되어 기뻤습니다!


이 프로젝트를 위해 두 가지 구성 요소가 있습니다.

  • 전화 앱 : 무제한 SMS, 브라우저 역할을 합니다.
  • 서버 : 무제한 인터넷, 전화를 대신하여 모든 실제 웹 페이지 로드를 수행합니다.

이 프로젝트를 시작할 때 이 도구는 나에게 유용한 도구가 되었으므로 Java 전용으로 Android 전용으로 작성했습니다 (Kotlin보다 Java 용 SMS에 대한 StackOverflow에 대한 답변이 더 많았습니다!). Node.js에서 프로젝트의 서버 측을 만들었습니다. 서버에서 JavaScript를 사용하는 것이 (존재하지 않는 곳) JavaScript가 없는 브라우저를 만드는 것이 유쾌하다고 생각했기 때문입니다.

Image showing data flow from phone to Twilio to server to the internet 


위의 이미지는 각 서비스 간의 정보 흐름을 보여줍니다. 앱을 통해 요청의 라이프 사이클을 살펴보고 따르십시오.


? Requesting a URL 


앱에서 가장 먼저 할 일은 로드 할 URL을 요청하는 것입니다. 아래 이미지는 URL을 입력하기 위한 텍스트 상자와 "이동"버튼을 제공하는 앱의 홈페이지 레이아웃을 보여줍니다. "이동"버튼을 누르면 몇 가지 일이 발생합니다.

  • 앱에 필요한 권한이 부여되지 않은 경우 SEND_SMS, READ_SMS 및 RECEIVE_SMS를 요청합니다.
  • URL이 단축됩니다 : https : // www. 는 존재해야 하기 때문에 제거 되며 이 응용 프로그램은 그런 멋진 것을 허용하지 않기 때문에 모든 쿼리 매개 변수가 제거됩니다.
  • 결과 URL은 Android의 내장 SMS API를 통해 Twilio에서 소유 한 전화 번호로 전송됩니다.

Image of the homepage of the app 


☎️ Setting up Twilio 


다음으로, Twilio에서 소유 한 전화 번호를 설정해야 합니다. Twilio의 웹 후크를 사용하여 내 번호로 전송 된 모든 SMS가 전달되어야 하는 URL을 지정할 수 있게 했습니다. 다음과 같이 webhook을 설정했습니다.

Image of Twilio message forwarding settings 


이것을 저장 한 후, 내가 설정 한 번호로 문자 메시지를 보내면 보낸 사람의 전화 번호, 발신 국가 및 국가와 같은 메시지에 대한 모든 종류의 정보가 포함 된 json 페이 로드와 함께 POST 요청을 지정된 URL로 보냅니다. 보내 졌을 때.


? 웹 페이지 가져 오기 및 SMS를 통해 전송 


이 시점에서 우리는 URL을 지정하고 Twilio를 통해 SMS를 통해 서버로 전달할 수 있었습니다. 진짜 재미를 시작하자! ?


React와 같은 프레임 워크에서 한 번에 작은 구성 요소로 작업하는 경향이 있는 개발자는 웹 사이트를 구성하는 HTML이 얼마나 큰지를 잊어 버릴 수 있습니다. 자주 사용하는 단일 상자 단일 버튼 단순 모양 검색 엔진에서 페이지 소스를 보면 HTML을 하나로 묶는 HTML의 길이가 거의 백만 문자 인 것을 알 수 있습니다. SMS는 160 자로 제한되며 SMS를 통해 직접 전송하는 데 1,300 개 이상의 메시지가 필요합니다!


무제한 메시지 전송 기능이 있더라도 SMS는 배달을 보장하지 않습니다. 전화로 받지 못한 메시지를 찾아서 다시 보내야 하므로 이미 많은 메시지를 한 번에 받는 데 오랜 시간이 걸리게 됩니다.


휴대 전화는 한 번에 ~ 10 개 이상이 되는 즉시 메시지를 삭제하는 경향이 있으므로 1,300 SMS를 10으로 줄이려고 목표를 설정하여 크기를 99 % 이상 줄였습니다.


그것은 야심 찬 목표였지만, 불가능한 목표와 흥미로운 문제는 저를 컴퓨터 과학으로 이끌었습니다. 그것을 때리는 것은 단지 Gzip을 사용하는 것보다 훨씬 더 창의적인 것을 얻는 것을 의미하므로 전통적인 압축에 관한 모든 아이디어를 버리고 작동했습니다.


압축 1 단계 : 안녕히 JavaScript! ? 


우리가 구축하는 브라우저는 자바 스크립트, CSS, 이미지 또는 90 년대 중 웹 사이트에서 찾을 수 없는 (애니메이션 일러스트 및 방문자 카운터 제외) 추가 오버 헤드 때문에 지원하지 않습니다. 약간의 이익을 위해. 요청한 웹 사이트에 대한 HTML을 얻은 후 가장 먼저 할 일은 브라우저에 명시적인 목적을 제공하지 않는 모든 것을 제거하는 것입니다.


이 단계에서 sanitize-html을 사용했습니다.이를 통해 일부 HTML에서 유지하거나 제거해야 하는 태그와 속성을 일반 목록 또는 해당 값의 함수로 지정할 수 있습니다. 내가 사용한 구성의 일부는 다음과 같습니다.


const sanitizeHtml = require('sanitize-html');

sanitizeHtml(HTML, {
  allowedTags: ['a', 'input', 'form'],
  allowedAttributes: {
    input: ['value', 'type', 'name'],
    a: ['href']
  },
  exclusiveFilter: (f) => {
    var att = f.attribs;
    return (f.tag == 'input' && att.type == 'hidden') ||
      (f.tag == 'a' && att && (att.href == undefined || 
      att.href.indexOf('policies') > -1));
  },
});

내가 설정 한 구성은 텍스트, <a>, <input> 및 <form> 태그 만 결과 HTML에 유지하고 해당 태그에서 값, 유형, 이름 및 href 속성 만 유지할 수 있습니다. 나는 이 브라우저에서 나가고 자하는 사용법에서, 그것들이 실질적인 가치를 제공하고 사이트와의 상호 작용을 허용 할 수 있는 유일한 것들이라고 생각했기 때문에 이 작은 목록을 결정했습니다. <style> 태그를 허용하지 않음으로써 모든 CSS를 잘라내므로 클래스 태그를 허용 할 필요가 없습니다 (JavaScript 및 기타 관련 태그에서도 마찬가지입니다).


sanitize-html을 사용하면 태그 및 속성 값의 기능에 따라 요소를 제거 할 수도 있습니다. 위에서 정의한 exclusiveFilter의 일부는 숨겨진 요소, 아무 데나 링크 및 개인 정보 보호 정책 및 이용 약관에 대한 링크를 제거했습니다. 어쨌든 클릭하지 않을 것이므로 공간을 낭비하는 이유는 무엇입니까?


압축 단계 2 : 일반적인 단어 단축 ? 


sanitize-html을 통해 HTML을 실행하면 많은 텍스트와 링크가 남습니다. 많은 언어에는 영어로 "the"또는 "and"와 같이 서면 텍스트로 많이 표시되는 매우 일반적인 단어가 있습니다. 이와 같은 단어가 있다는 것을 알고 있기 때문에 결정적인 방식으로 단어를 압축 할 수 있습니다. "a"나 "I"가 아닌 단일 문자로 바꾸면 됩니다. 텍스트가 "t"및 "n"또는 "n"과 같이 압축 된 경우 이러한 단어에 대한 압축 및 압축 해제는 각 쌍에 대해 "find-and-replace-all"이 됩니다. 유효한 단어. 그게 공룡이고 가장 좋은 것 ➜ S는 t 공룡 n t 가장 좋은 것


압축 단계 3 : 시소러스-렉스 ? 


완전히 말도 안되고 불필요한 것을 만드는 주제를 계속 유지하기 위해 텍스트를 압축하는 두 번째 방법은 동의어 사전 API를 사용하는 것입니다. 아래 그림과 같이 교도소 il 감옥과 같은 대략적인 의미를 유지하면서 너무 길고 짧아 질 수 있는 영어 단어가 많이 있습니다 (12 자에서 4 자 압축). 동의어 사전 API를 사용하면 긴 단어에 대한 동의어를 찾아서 대체 할 수 있습니다. 이 방법은 절대적으로 손실 압축 (보통 실제 데이터와 의미 모두)이지만, 작동하며 재미 있습니다!

Example compression of penitentiary to jail 


압축 단계 4 : 링크에 대한 새로운 접근 방식 ? 


HTML이 렌더링 될 때 숨겨져 있기 때문에 처음에는 분명하지 않았지만 앵커 태그의 링크가 나머지 공간의 대부분을 차지하고 있었습니다. 페이지에서 10 자 이하의 파란색 단어 뒤에는 200 자 길이의 URL이 있으며 이는 문제입니다. 전화에서 링크를 미리 보는 것은 고통스럽기 때문에 클릭 할 때 링크가 원하는 곳으로 연결되는 한 링크가 무엇인지 상관하지 않습니다. 이러한 동작으로 인해 <a>의 실제 href 값을 보내는 것이 중요하지 않다고 결정했으며 링크를 클릭하면 원하는 위치로 이동할 수 있으면 많은 공간을 절약 할 수 있습니다.


Example link compression 


sanitize-html을 사용하면 속성 값을 수정하는 함수를 정의 할 수 있는데, 이는 링크를 수정하는 데 사용한 것입니다. HTML에서 링크가 발견되면 웹 사이트의 전화 번호와 실제 링크 URL이 아래 함수로 전달됩니다.이 함수는 {phone_number} _ {shortUrl} / realUrl의 키 / 값 쌍을 Redis에 저장합니다. 여기서 shortUrl 임의의 3 문자열입니다.


const redis = require('redis');
const redisClient = redis.createClient(process.env.REDIS_URL); 

const urlShortener = (phoneNum, url) => {
  if (url) {
    const urlShort = Math.random().toString(36).substr(2, 3);
    redisClient.set(`${phoneNum}_${urlShort}`, url);
    return urlShort;
  }
  return '';
};

최종 HTML에는 모든 링크가 위 코드에서 생성 된 짧은 코드로 대체됩니다. 앱에서 링크를 클릭하면 해당 짧은 코드가 SMS를 통해 서버로 전송되어 형식을 알고 Redis에서 전체 값을 찾고 실제 URL에서 웹 사이트를 검색합니다.


거의 완전히 링크 된 Wikipedia와 같은 웹 사이트의 경우 압축에 많은 가치가 추가됩니다.


압축 단계 5 : HTML에서 횡설수설 Ω 


이제 모든 텍스트를 압축하고 페이지에서 가능한 한 많은 HTML을 제거 했으므로 웹 페이지를 앱으로 보내기 전에 마지막 단계를 수행 할 준비가 되었습니다!


우리가 사용하는 SMS 문자셋을 GSM-7이라고 하며 모든 영어 문자, 숫자, 기본 기호 및 그리스 문자를 포함합니다! 우리는 압축의 2 부에서 이미 모든 단일 영어 문자를 모두 사용했지만 수학이나 과학에 관한 웹 사이트를 보지 않는 한 HTML에는 그리스 문자가 없을 것입니다.


이전과 비슷한 "찾기 및 바꾸기"방법으로 이러한 문자로 유한 HTML 키워드 세트를 압축 할 수 있습니다. 아래 이미지는 요소와 일치하는 기호 사이의 색상 매핑을 보여줍니다. <와 함께 입력 또는 값과 함께 = 또는 "와 같이 표시되는 문자를 결합하여 공간을 절약 할 수 있습니다.이 매핑은 명시 적이므로 반대 방향으로 이동하면 압축을 풀기가 쉽습니다.

Example HTML compression 


이륙 준비 ? 


압축을 위해 설정 한 목표는 웹 페이지를 1,300+ SMS에서 10으로 낮추는 것이었습니다. 어떻게 해야 합니까? 나는 그것을 3 SMS로 줄였다. 그리고 가장 좋은 부분은? 내가 작성한 코드 중 어느 것도 이 웹 사이트에만 해당되는 것이 아니며 텍스트 기반 페이지에 일반적입니다.


웹 사이트가 모두 압축되었으므로 서버에서 다시 휴대 전화로 보내야 합니다. Twilio는 모든 무거운 작업을 수행하는 훌륭한 노드 도우미 라이브러리를 제공합니다. 다음은 메시지를 전화로 다시 보내는 데 필요한 전부입니다.


const twilioClient = require('twilio')(
    process.env.TWILIO_SID, process.env.TWILIO_AUTH_TOKEN);

// Divide HTML into the max sized SMS - 5
const smss = HTML.match(/.{155}/g);

// Send out all the SMS via Twilio
smss.map((sms, index) => {
    twilioClient.messages.create({
        body: `${index+1}/${smss.length} ${sms}`,
        from: process.env.TWILIO_NUMBER,
        to: req.body.From,
    });
});


? 앱에서 웹 사이트 재구성 


Android 측에서 BroadcastReceiver는 Twilio 번호에서 들어오는 SMS를 수신하도록 설정되어 있습니다. 웹 사이트를 구성하는 모든 SMS가 수신되면 SMS는 압축 단계를 거꾸로하여 연결되어 압축 해제됩니다 (Thesaurus-Rex ski 이상 건너 뛰기). 결과 HTML은 Webview 구성 요소 (URL 또는 HTML을 허용하는 앱 내의 Chrome 브라우저)로 전달되고 웹 사이트가 표시됩니다!


google.ca의 최종 결과는 압축 된 SMS 텍스트를 포함하는 아래 이미지와 같습니다. 이것은 15 년 전 웹 사이트의 모습이며, 무료 인터넷 연결을 하기에는 너무 허름하지 않습니다!

What google.ca looks like in the app 


이것이 내가 시스템을 속이고 무제한 인터넷을 얻는 방법입니다! 이 방법은 텍스트 기반 웹 사이트에서만 작동하며 속도가 느릴 수 있지만 (결국 전화 접속이라고 함) 무료로 이 응용 프로그램을 사용하여 10 초 안에 검색 결과를 로드할 수 있음을 알고 있습니다 내가 여전히 올바른 방향으로 걷고 있는지 확인하기 위해 몇 분마다 wifi 핫스팟을 찾아야 합니다.