Skip to content

Add Slack message parsing #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!---
Please write your PR name in the present imperative tense. Examples of present imperative tense are:
"Fix issue in the dispatcher where…", "Improve our handling of…", etc."

For more information on Pull Requests, you can reference here:
https://success.vanillaforums.com/kb/articles/228-using-pull-requests-to-contribute
-->
## Describe your changes


## Non-obvious technical information


## Checklist before requesting a review
- [ ] The code runs successfully.

```commandline
HERE IS SOME COMMAND LINE OUTPUT
```
34 changes: 34 additions & 0 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Audit

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:

audit:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.22

- name: Verify dependencies
run: go mod verify

- name: Build
run: go build -v ./...

- name: Run go vet
run: go vet ./...

- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@latest

- name: Run staticcheck
run: staticcheck ./...
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@
# Go workspace file
go.work
go.work.sum

# IDE directories and misc. files
.idea
.vscode
**/.DS_Store
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
default: lint

.PHONY: init
init:
go mod download

.PHONY: lint
lint:
go mod tidy
go fmt ./...
go vet ./...
staticcheck ./...
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# golang-scripting
# Various Scripts in the Key of Golang
Various scripts written in Golang.

## Scripts

### Slack Message Parser


#### Instructions
```console
cp [YOUR_ARCHIVE_PATH_HERE]/*.json ./SlackMessages/
go run slack_message_parser.go
```
166 changes: 166 additions & 0 deletions cmd/slackMessageParser/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* Copyright (c) 2024 Michael Plunkett (https://github.com/michplunkett)
* All rights reserved.
* Used to parse Slack messages.
*/

package main

import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/gocarina/gocsv"
)

type Message struct {
TimeStamp string
UserID string `json:"user"`
TS string `json:"ts"`
Type string `json:"type"`
ClientMessageID string `json:"client_msg_id"`
Text string `json:"text,omitempty"`
UserProfile *UserProfile `json:"user_profile,omitempty"`
Attachments *[]*Attachment `json:"attachments,omitempty"`
Files *[]File `json:"files,omitempty"`
IsUpload bool `json:"upload,omitempty"`
}

type UserProfile struct {
ProfileImage string `json:"image_72,omitempty"`
FirstName string `json:"first_name,omitempty"`
RealName string `json:"real_name,omitempty"`
DisplayName string `json:"display_name,omitempty"`
Name string `json:"name,omitempty"`
}

type Attachment struct {
Text string `json:"text"`
Fallback string `json:"fallback"`
FromURL string `json:"from_url"`
ServiceName string `json:"service_name"`
ID int `json:"id"`
OriginalURL string `json:"original_url"`
}

type File struct {
ID string `json:"id"`
Name string `json:"name"`
Title string `json:"title"`
MimeType string `json:"mimetype"`
FileType string `json:"pretty_type"`
IsExternal bool `json:"is_external"`
IsPublic bool `json:"is_public"`
DownloadLink string `json:"url_private_download"`
Height int `json:"original_w"`
Width int `json:"original_h"`
}

type CSVRecord struct {
TimeStamp string
UserID string
UserName string
RealName string
MessageType string
Text string
Attachments []string
Files []string
}

func main() {
if _, err := os.Stat("../../SlackMessages"); os.IsNotExist(err) {
log.Fatal("the ./SlackMessages directory does not exist")
}

files, err := filepath.Glob("../../SlackMessages/*.json")
if err != nil {
log.Fatal(err)
}

if len(files) == 0 {
log.Fatal("could not find *.json files in the ./SlackMessages directory")
}

messages := make([]*Message, 0)

for _, file := range files {
bytes, err := os.ReadFile(file)
if err != nil {
fmt.Printf("error occured while opening %s: %+v\n", file, err)
continue
}

fileMessages := make([]*Message, 0)
err = json.Unmarshal(bytes, &fileMessages)
if err != nil {
fmt.Printf("error occured while parsing JSON from %s: %+v\n", file, err)
continue
}

messages = append(messages, fileMessages...)
}

csvRecords := make([]*CSVRecord, 0)
for _, msg := range messages {
record := &CSVRecord{
UserID: msg.UserID,
UserName: "",
RealName: "",
MessageType: msg.Type,
Attachments: make([]string, 0),
Files: make([]string, 0),
}

timeStampSplit := strings.Split(msg.TS, ".")
seconds, err := strconv.ParseInt(timeStampSplit[0], 10, 64)
if err != nil {
fmt.Printf("error occured while parsing seconds: %+v\n", err)
continue
}

nanoseconds, err := strconv.ParseInt(timeStampSplit[1], 10, 64)
if err != nil {
fmt.Printf("error occured while parsing nanoseconds: %+v\n", err)
continue
}

record.TimeStamp = time.Unix(seconds, nanoseconds).Format(time.RFC3339)

if msg.UserProfile != nil {
record.UserName = msg.UserProfile.Name
record.RealName = msg.UserProfile.RealName
}

if msg.Text != "" {
record.Text = msg.Text
}

if msg.Attachments != nil {
for _, attachment := range *msg.Attachments {
record.Attachments = append(record.Attachments, attachment.OriginalURL)
}
}

if msg.Files != nil {
for _, file := range *msg.Files {
record.Files = append(record.Files, file.DownloadLink)
}
}

csvRecords = append(csvRecords, record)
}

csvFile, err := os.Create("../../slack_records.csv")
if err != nil {
log.Fatal(err)
}
defer csvFile.Close()

_ = gocsv.MarshalFile(csvRecords, csvFile)
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/michplunkett/golang-scripting

go 1.22.4

require github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ=
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
Loading