Advertisement
Guest User

Untitled

a guest
Mar 15th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 7.68 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "net/http"
  5.     "net/url"
  6.     "io/ioutil"
  7.     "fmt"
  8.     "encoding/json"
  9.     "log"
  10.     "strconv"
  11.     "io"
  12.     "bytes"
  13.     "mime/multipart"
  14.     "time"
  15.     "math/rand"
  16. )
  17.  
  18. const (
  19.     accessToken = "11s9bd8ad4f07a3df320cf21d589bbf09aeacd7d372d30f0443603b3db189a0a8520552cc1a679010779"
  20.     groupId = "135209264"
  21.     apiV = "5.80"
  22.     maxAttempt = 10
  23.     maxLength = 500
  24. )
  25.  
  26. type (
  27.     LongPoll struct {
  28.         Response struct {
  29.             Key    string `json:"key"`
  30.             Server string `json:"server"`
  31.             Ts     int64 `json:"ts"`
  32.         }
  33.     }
  34.  
  35.     Event struct {
  36.         Ts string `json:"ts"`
  37.         Updates []Update `json:"updates"`
  38.     }
  39.  
  40.     Update struct {
  41.         Type string `json:"type"`
  42.         Object Message `json:"object"`
  43.         GroupId int64 `json:"group_id"`
  44.     }
  45.  
  46.     Message struct {
  47.         Date int64 `json:"date"`
  48.         Out int8 `json:"out"`
  49.         UserId int64 `json:"user_id"`
  50.         Body string `json:"body"`
  51.         Attachments *[]Attachment `json:"attachments"`
  52.         Emoji *int `json:"emoji"`
  53.     }
  54.  
  55.     Attachment struct {
  56.         Type string `json:"type"`
  57.         Doc *Doc `json:"doc"`
  58.     }
  59.  
  60.     Doc struct {
  61.         Id int64 `json:"id"`
  62.         OwnerId int64 `json:"owner_id"`
  63.         Title string `json:"title"`
  64.         Size int64 `json:"size"`
  65.         Ext string `json:"ext"`
  66.         Url string `json:"url"`
  67.         Date int64 `json:"date"`
  68.         Type int `json:"type"`
  69.     }
  70.  
  71.     SendMessage struct {
  72.         Response int `json:"response"`
  73.     }
  74.  
  75.     /* Uploads */
  76.     UploadURL struct {
  77.         Response struct {
  78.             UploadUrl string `json:"upload_url"`
  79.         }
  80.     }
  81.  
  82.     DocUploaded struct {
  83.         File string `json:"file"`
  84.     }
  85. )
  86.  
  87. func main() {
  88.     rand.Seed(time.Now().Unix())
  89.     startLongPoll()
  90. }
  91.  
  92. /* Long Poll */
  93. func startLongPoll() {
  94.     longPollParams := getLongPollServer()
  95.     log.Print("get long poll server")
  96.     for {
  97.         serverURL := fmt.Sprintf("%s?act=a_check&key=%s&ts=%d&wait=25", longPollParams.Response.Server, longPollParams.Response.Key, longPollParams.Response.Ts)
  98.         resp, err := http.Get(serverURL)
  99.         if err != nil {
  100.             log.Print("error connect to longPoll server")
  101.             break
  102.         }
  103.         bodyBuf, err := ioutil.ReadAll(resp.Body)
  104.         if err != nil {
  105.             log.Print("error read from longPoll server")
  106.             break
  107.         }
  108.         event:= Event{}
  109.         // log.Print(string(bodyBuf))
  110.         if err := json.Unmarshal(bodyBuf, &event); err != nil {
  111.             fmt.Print("error parse json from longPoll server: " + string(bodyBuf))
  112.             break
  113.         }
  114.         longPollParams.Response.Ts, _ = strconv.ParseInt(event.Ts, 0, 64)
  115.         go processEvent(event)
  116.         // break
  117.     }
  118.     startLongPoll()
  119. }
  120.  
  121. func processEvent(event Event)  {
  122.     // log.Print(len(event.Updates))
  123.     for i := range event.Updates {
  124.         update:= event.Updates[i]
  125.         switch update.Type {
  126.             case "message_new":
  127.                 TextLength := len([]rune(update.Object.Body))
  128.                 if TextLength > maxLength {
  129.                     sendMessage(update.Object.UserId, fmt.Sprintf("new code: В одном сообщении можно озвучить только %d символов. У тебя %s", maxLength, declOfNum(TextLength, [3]string{
  130.                         "символ",
  131.                         "символа",
  132.                         "символов",
  133.                     })))
  134.                 } else {
  135.                     go typing(update.Object.UserId)
  136.                     go processMessage(update.Object)
  137.                 }
  138.                 break
  139.         }
  140.     }
  141. }
  142.  
  143. func processMessage(message Message)  {
  144.     /* if message.UserId == 383520740 {
  145.         log.Print(message)
  146.     } */
  147.     sendVoice(message.UserId, message.Body, 0)
  148. }
  149.  
  150. func getLongPollServer() LongPoll {
  151.     data := url.Values{}
  152.     data.Add("group_id", groupId)
  153.     longPoll:= LongPoll{}
  154.     if err := json.Unmarshal(_api("groups.getLongPollServer", data), &longPoll); err != nil {
  155.         log.Fatal("unmarshal response json failed:", err)
  156.     }
  157.     return longPoll
  158. }
  159.  
  160.  
  161. /* VK API */
  162. func _api(method string, data url.Values) []byte {
  163.     data.Add("user_ids", "1")
  164.     data.Add("v", apiV)
  165.     data.Add("access_token", accessToken)
  166.     resp, err := http.PostForm("https://api.vk.com/method/" + method, data)
  167.     if err != nil {
  168.         return nil
  169.     }
  170.     defer resp.Body.Close()
  171.     bodyBuf, err := ioutil.ReadAll(resp.Body)
  172.     return bodyBuf
  173. }
  174.  
  175. func typing(PeerID int64) {
  176.     data := url.Values{}
  177.     data.Add("peer_id", toString(PeerID))
  178.     data.Add("type", "typing")
  179.     _api("messages.setActivity", data)
  180. }
  181.  
  182. func sendMessage(UserID int64, Text string) {
  183.     data := url.Values{}
  184.     data.Add("peer_id", toString(UserID))
  185.     data.Add("message", Text)
  186.     _api("messages.send", data)
  187. }
  188.  
  189. func sendVoice(peerID int64, Text string, attempt int) bool {
  190.     attempt++
  191.     if attempt > maxAttempt {
  192.         sendMessage(peerID, "Не получилось озвучить :(")
  193.         return false
  194.     }
  195.     data := url.Values{}
  196.     data.Add("peer_id", toString(peerID))
  197.     data.Add("type", "audio_message")
  198.     uploadURL:= UploadURL{}
  199.     if err := json.Unmarshal(_api("docs.getMessagesUploadServer", data), &uploadURL); err != nil {
  200.         return sendVoice(peerID, Text, attempt)
  201.     }
  202.     if uploadURL.Response.UploadUrl == "" {
  203.         return sendVoice(peerID, Text, attempt)
  204.     }
  205.     bodyBuf := &bytes.Buffer{}
  206.     bodyWriter := multipart.NewWriter(bodyBuf)
  207.     fileWriter, err := bodyWriter.CreateFormFile("file", "bot_maxim.mp3")
  208.     if err != nil {
  209.         log.Print("SendVoice #1", err)
  210.         return sendVoice(peerID, Text, attempt)
  211.     }
  212.     data = url.Values{}
  213.     data.Add("text", Text)
  214.     data.Add("voice", "max")
  215.     resp, err := http.PostForm(getVoiceServer(), data)
  216.     if err != nil {
  217.         log.Print("SendVoice #2", err)
  218.         return sendVoice(peerID, Text, attempt)
  219.     }
  220.     defer resp.Body.Close()
  221.     _, err = io.Copy(fileWriter, resp.Body)
  222.     if err != nil {
  223.         log.Print("SendVoice #3", err)
  224.         return sendVoice(peerID, Text, attempt)
  225.     }
  226.     contentType := bodyWriter.FormDataContentType()
  227.     bodyWriter.Close()
  228.     resp, err = http.Post(uploadURL.Response.UploadUrl, contentType, bodyBuf)
  229.     if err != nil {
  230.         log.Print("SendVoice #4", err)
  231.         return sendVoice(peerID, Text, attempt)
  232.     }
  233.     defer resp.Body.Close()
  234.     body, err := ioutil.ReadAll(resp.Body)
  235.     if err != nil {
  236.         log.Print("SendVoice #5", err)
  237.         return sendVoice(peerID, Text, attempt)
  238.     }
  239.     uploaded := DocUploaded{}
  240.     err = json.Unmarshal(body, &uploaded)
  241.     if err != nil || uploaded.File == "" {
  242.         return sendVoice(peerID, Text, attempt)
  243.     }
  244.     data = url.Values{}
  245.     data.Add("peer_id", toString(peerID))
  246.     data.Add("file", uploaded.File)
  247.     data.Add("code", "" +
  248.         "var peer_id = Args.peer_id;" +
  249.         "var doc = API.docs.save({file: Args.file, title: \"bot_maxim.mp3\", tags: \"bot_maxim\"})[0];" +
  250.         "if (parseInt(doc.owner_id) == 0) {" +
  251.         "   return -1;" +
  252.         "}" +
  253.         "var isMember = API.groups.isMember({group_id: 135209264, user_id: peer_id});" +
  254.         "var message_text = \"\";" +
  255.         "var last_send_id = -1;" +
  256.         "if (isMember == 0) {" +
  257.         "   message_text = \"Нравится? 👉 [club135209264|Подпишись!] 💙 И расскажи друзьям 👌\";" +
  258.         "}" +
  259.         "last_send_id = API.messages.send({peer_id: peer_id, message: message_text, attachment: \"doc\" + doc.owner_id + \"_\" + doc.id});" +
  260.         "if (isMember == 0) {" +
  261.         "   last_send_id = API.messages.send({peer_id: peer_id, message: \"vk.com/bot_maxim\"});" +
  262.         "}" +
  263.         "return last_send_id;")
  264.     sendMessage := SendMessage{}
  265.     executeAPI := _api("execute", data)
  266.     if err := json.Unmarshal(executeAPI, &sendMessage); err != nil {
  267.         log.Print("SendVoice #7", err)
  268.         return sendVoice(peerID, Text, attempt)
  269.     }
  270.     if sendMessage.Response != 0 {
  271.         return sendVoice(peerID, Text, attempt)
  272.     }
  273.     return true
  274. }
  275.  
  276. func declOfNum(number int, titles [3]string) string {
  277.     cases := [6]int{2, 0, 1, 1, 1, 2}
  278.     index := 0
  279.     if number % 100 > 4 && number % 100 < 20 {
  280.         index = 2
  281.     } else if number % 10 < 5 {
  282.         index = cases[number % 10]
  283.     } else {
  284.         index = cases[5]
  285.     }
  286.     return fmt.Sprintf("%d %s", number, titles[index])
  287. }
  288.  
  289. func getVoiceServer() string {
  290.     // n := rand.Int() % len(voiceServers)
  291.     return "http://localhost/voice" // fmt.Sprintf("http://%s/voice", voiceServers[n])
  292. }
  293.  
  294. func toString(value int64) string {
  295.     return fmt.Sprintf("%v", value)
  296. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement