github.com/sharovik/devbot@v1.0.1-0.20240308094637-4a0387c40516/internal/client/slack.go (about)

     1  package client
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"io"
     8  	"mime/multipart"
     9  	"net/http"
    10  	"os"
    11  
    12  	"github.com/sharovik/devbot/internal/dto"
    13  	"github.com/sharovik/devbot/internal/log"
    14  )
    15  
    16  // SlackClient client for message api calls
    17  type SlackClient struct {
    18  	BaseMessageClient
    19  	Client     *http.Client
    20  	BaseURL    string
    21  	OAuthToken string
    22  }
    23  
    24  // AttachFileTo method for attachment file send to specific channel
    25  func (client SlackClient) AttachFileTo(channel string, pathToFile string, filename string) ([]byte, int, error) {
    26  	log.Logger().StartMessage("Slack attachment request")
    27  
    28  	var buf bytes.Buffer
    29  
    30  	writer := multipart.NewWriter(&buf)
    31  
    32  	log.Logger().Debug().
    33  		Str("channel", channel).
    34  		Str("file_path", pathToFile).
    35  		Str("filename", filename).
    36  		Msg("Received parameters")
    37  
    38  	fieldWriter, err := writer.CreateFormField("channels")
    39  	if err != nil {
    40  		return nil, 0, err
    41  	}
    42  
    43  	if _, err := fieldWriter.Write([]byte(channel)); err != nil {
    44  		return nil, 0, err
    45  	}
    46  
    47  	part, err := writer.CreateFormFile("file", filename)
    48  	if err != nil {
    49  		return nil, 0, err
    50  	}
    51  
    52  	file, err := os.Open(pathToFile)
    53  	if err != nil {
    54  		return nil, 0, err
    55  	}
    56  
    57  	if _, err = io.Copy(part, file); err != nil {
    58  		return nil, 0, err
    59  	}
    60  
    61  	writer.Close()
    62  	file.Close()
    63  
    64  	return client.HTTPClient.Post("/files.upload", &buf, map[string]string{})
    65  }
    66  
    67  // SendMessage method for post message send through simple API request
    68  func (client SlackClient) SendMessage(message dto.BaseChatMessage) (resp dto.BaseResponseInterface, status int, err error) {
    69  	log.Logger().Debug().Interface("message", message).Msg("Start chat.postMessage")
    70  	byteStr, err := json.Marshal(dto.SlackRequestChatPostMessage{
    71  		Channel:           message.Channel,
    72  		Text:              message.Text,
    73  		AsUser:            message.AsUser,
    74  		ThreadTS:          message.ThreadTS,
    75  		Ts:                message.Ts,
    76  		DictionaryMessage: dto.DictionaryMessage{},
    77  		OriginalMessage:   dto.SlackResponseEventMessage{},
    78  	})
    79  	if err != nil {
    80  		return resp, 0, err
    81  	}
    82  
    83  	response, statusCode, err := client.HTTPClient.Post("/chat.postMessage", byteStr, map[string]string{})
    84  	if err != nil {
    85  		log.Logger().AddError(err).
    86  			RawJSON("response", response).
    87  			Int("status_code", statusCode).
    88  			Msg("Failed send message")
    89  		return resp, statusCode, err
    90  	}
    91  
    92  	var dtoResponse dto.SlackResponseChatPostMessage
    93  	dtoResponse.SetByteResponse(response)
    94  	if err := json.Unmarshal(response, &dtoResponse); err != nil {
    95  		return resp, statusCode, err
    96  	}
    97  
    98  	if !dtoResponse.Ok {
    99  		return &dtoResponse, statusCode, errors.New(dtoResponse.Error)
   100  	}
   101  
   102  	log.Logger().Debug().Interface("message", message).Msg("Finish chat.postMessage")
   103  	dtoResponse.SetByteResponse(response)
   104  
   105  	return &dtoResponse, statusCode, nil
   106  }
   107  
   108  // GetConversationsList method which returns the conversations list of current workspace
   109  func (client SlackClient) GetConversationsList() (dto.SlackResponseConversationsList, int, error) {
   110  	response, statusCode, err := client.HTTPClient.Get("/conversations.list", map[string]string{})
   111  	if err != nil {
   112  		return dto.SlackResponseConversationsList{}, statusCode, err
   113  	}
   114  
   115  	var dtoResponse dto.SlackResponseConversationsList
   116  	if err := json.Unmarshal(response, &dtoResponse); err != nil {
   117  		return dto.SlackResponseConversationsList{}, statusCode, err
   118  	}
   119  
   120  	if !dtoResponse.Ok {
   121  		return dtoResponse, statusCode, errors.New(dtoResponse.Error)
   122  	}
   123  
   124  	return dtoResponse, statusCode, nil
   125  }
   126  
   127  // GetUsersList method which returns the users list of current workspace
   128  func (client SlackClient) GetUsersList() (dto.SlackResponseUsersList, int, error) {
   129  	response, statusCode, err := client.HTTPClient.Get("/users.list", map[string]string{})
   130  	if err != nil {
   131  		return dto.SlackResponseUsersList{}, statusCode, err
   132  	}
   133  
   134  	var dtoResponse dto.SlackResponseUsersList
   135  	if err := json.Unmarshal(response, &dtoResponse); err != nil {
   136  		return dto.SlackResponseUsersList{}, statusCode, err
   137  	}
   138  
   139  	if !dtoResponse.Ok {
   140  		return dtoResponse, statusCode, errors.New(dtoResponse.Error)
   141  	}
   142  
   143  	return dtoResponse, statusCode, nil
   144  }