API Reference

Complete technical reference for the Mattermost PDF Dekont Parser Plugin API and internal functions.

Table of contents

  1. Plugin Interface
    1. Core Plugin Structure
    2. Required Plugin Hooks
      1. OnActivate
      2. MessageHasBeenPosted
  2. Core Functions
    1. File Processing
      1. processFileIfPDF
      2. downloadFile
    2. PDF Processing
      1. processPDF
      2. extractTextFromPDF
  3. Data Structures
    1. TransactionInfo
    2. FieldPattern
  4. Field Extraction Functions
    1. extractRecipient
    2. extractDescription
    3. extractAmount
  5. Utility Functions
    1. cleanText
    2. formatTransactionInfo
    3. isPDF
  6. Error Handling
    1. Error Types
      1. PDFProcessingError
      2. FieldExtractionError
    2. Error Handling Patterns
  7. Configuration
    1. Plugin Configuration
    2. Configuration Functions
      1. loadConfiguration
      2. getConfiguration
  8. Constants
    1. File Processing
    2. Field Patterns
  9. Performance Metrics
    1. Benchmarking Functions
      1. BenchmarkPDFProcessing
    2. Memory Usage
      1. Memory-Efficient Processing
  10. Testing API
    1. Test Helpers
      1. LoadTestPDF
      2. CreateMockPlugin
      3. AssertTransactionInfo
    2. Test Data
  11. Integration Examples
    1. Custom Field Extraction
    2. Webhook Integration
  12. Support

Plugin Interface

Core Plugin Structure

type Plugin struct {
    plugin.MattermostPlugin
    
    // Internal state
    configuration atomic.Value
}

Required Plugin Hooks

OnActivate

func (p *Plugin) OnActivate() error

Description: Called when the plugin is activated. Initializes the plugin state and validates configuration.

Returns: error - nil if activation successful, error otherwise

Example:

func (p *Plugin) OnActivate() error {
    p.API.LogInfo("PDF Dekont Parser Plugin activated")
    
    // Initialize configuration
    if err := p.loadConfiguration(); err != nil {
        return fmt.Errorf("failed to load configuration: %w", err)
    }
    
    return nil
}

MessageHasBeenPosted

func (p *Plugin) MessageHasBeenPosted(c *plugin.Context, post *model.Post) *model.Post

Description: Called when a message is posted. Checks for PDF file attachments and processes them.

Parameters:

Returns: *model.Post - Modified post with extracted information (if applicable)

Example:

func (p *Plugin) MessageHasBeenPosted(c *plugin.Context, post *model.Post) *model.Post {
    if len(post.FileIds) == 0 {
        return nil
    }
    
    for _, fileId := range post.FileIds {
        if err := p.processFileIfPDF(post, fileId); err != nil {
            p.API.LogError("Failed to process file", "error", err.Error())
        }
    }
    
    return nil
}

Core Functions

File Processing

processFileIfPDF

func (p *Plugin) processFileIfPDF(post *model.Post, fileId string) error

Description: Checks if a file is a PDF and processes it for transaction data extraction.

Parameters:

Returns: error - nil if processing successful, error otherwise

Example Usage:

err := p.processFileIfPDF(post, fileId)
if err != nil {
    p.API.LogError("PDF processing failed", "error", err.Error())
}

downloadFile

func (p *Plugin) downloadFile(fileId string) ([]byte, *model.FileInfo, error)

Description: Downloads file content from Mattermost file storage.

Parameters:

Returns:

PDF Processing

processPDF

func (p *Plugin) processPDF(content []byte) (*TransactionInfo, error)

Description: Main PDF processing function that extracts text and parses transaction fields.

Parameters:

Returns:

Example:

pdfData, err := ioutil.ReadFile("sample.pdf")
if err != nil {
    return err
}

info, err := p.processPDF(pdfData)
if err != nil {
    return fmt.Errorf("PDF processing failed: %w", err)
}

fmt.Printf("Recipient: %s\n", info.Recipient)

extractTextFromPDF

func (p *Plugin) extractTextFromPDF(content []byte) (string, error)

Description: Extracts plain text content from PDF using the pdf library.

Parameters:

Returns:


Data Structures

TransactionInfo

type TransactionInfo struct {
    Recipient   string `json:"recipient"`   // Alıcı
    Description string `json:"description"` // Açıklama  
    Amount      string `json:"amount"`      // İşlem Tutarı
}

Description: Structure containing extracted transaction information.

Fields:

Example:

info := &TransactionInfo{
    Recipient:   "AHMET YILMAZ",
    Description: "Freelance Payment", 
    Amount:      "2,500.00 TL",
}

FieldPattern

type FieldPattern struct {
    Name    string
    Regex   *regexp.Regexp
    Cleaner func(string) string
}

Description: Pattern definition for field extraction.

Fields:


Field Extraction Functions

extractRecipient

func (p *Plugin) extractRecipient(text string) (string, error)

Description: Extracts recipient information from PDF text using predefined patterns.

Parameters:

Returns:

Supported Patterns:

Example:

text := "ALICI: MEHMET KAYA\nTUTAR: 1000 TL"
recipient, err := p.extractRecipient(text)
if err == nil {
    fmt.Println("Recipient:", recipient) // Output: MEHMET KAYA
}

extractDescription

func (p *Plugin) extractDescription(text string) (string, error)

Description: Extracts transaction description from PDF text.

Parameters:

Returns:

Supported Patterns:

extractAmount

func (p *Plugin) extractAmount(text string) (string, error)

Description: Extracts transaction amount from PDF text.

Parameters:

Returns:

Supported Patterns:


Utility Functions

cleanText

func (p *Plugin) cleanText(text string) string

Description: Cleans extracted text by removing extra whitespace and formatting.

Parameters:

Returns:

Cleaning Operations:

formatTransactionInfo

func (p *Plugin) formatTransactionInfo(info *TransactionInfo) string

Description: Formats transaction information into a structured display format.

Parameters:

Returns:

Example Output:

📄 PDF Dekont Bilgileri:
━━━━━━━━━━━━━━━━━━━━━━━━━━

👤 Alıcı: AHMET YILMAZ
📝 Açıklama: Freelance Payment
💰 İşlem Tutarı: 2,500.00 TL

━━━━━━━━━━━━━━━━━━━━━━━━━━

isPDF

func (p *Plugin) isPDF(fileInfo *model.FileInfo) bool

Description: Checks if a file is a PDF based on MIME type and extension.

Parameters:

Returns:


Error Handling

Error Types

PDFProcessingError

type PDFProcessingError struct {
    Operation string
    Filename  string
    Err       error
}

func (e *PDFProcessingError) Error() string {
    return fmt.Sprintf("PDF processing failed during %s for file %s: %v", 
        e.Operation, e.Filename, e.Err)
}

FieldExtractionError

type FieldExtractionError struct {
    Field string
    Err   error
}

func (e *FieldExtractionError) Error() string {
    return fmt.Sprintf("failed to extract %s: %v", e.Field, e.Err)
}

Error Handling Patterns

// Graceful error handling with logging
func (p *Plugin) processWithErrorHandling(content []byte, filename string) error {
    defer func() {
        if r := recover(); r != nil {
            p.API.LogError("Panic during PDF processing", 
                "filename", filename, "panic", r)
        }
    }()
    
    info, err := p.processPDF(content)
    if err != nil {
        return &PDFProcessingError{
            Operation: "text extraction",
            Filename:  filename,
            Err:       err,
        }
    }
    
    if info.Recipient == "" {
        return &FieldExtractionError{
            Field: "recipient",
            Err:   errors.New("no recipient pattern matched"),
        }
    }
    
    return nil
}

Configuration

Plugin Configuration

type Configuration struct {
    DebugLogging bool `json:"debug_logging"`
    MaxFileSize  int  `json:"max_file_size"`
}

Description: Plugin configuration structure.

Fields:

Configuration Functions

loadConfiguration

func (p *Plugin) loadConfiguration() error

Description: Loads plugin configuration from Mattermost settings.

getConfiguration

func (p *Plugin) getConfiguration() *Configuration

Description: Returns current plugin configuration.


Constants

File Processing

const (
    MaxPDFSize         = 10 * 1024 * 1024 // 10MB
    MaxProcessingTime  = 30 * time.Second
    MaxPagesToProcess  = 10
)

Field Patterns

const (
    RecipientPattern    = `(?i)(ALICI|ALAN|YARARLANICI|HESAP SAHİBİ)[^:]*:\s*(.+)`
    DescriptionPattern  = `(?i)(AÇIKLAMA|ACIKLAMA|REFERANS)[^:]*:\s*(.+)`
    AmountPattern      = `(?i)(TUTAR|İŞLEM TUTARI|GÖNDERILEN)[^:]*:\s*([0-9.,]+\s*[A-Z]+)`
)

Performance Metrics

Benchmarking Functions

BenchmarkPDFProcessing

func BenchmarkPDFProcessing(b *testing.B) {
    plugin := &Plugin{}
    testData := loadTestPDF()
    
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _, _ = plugin.processPDF(testData)
    }
}

Expected Performance:

Memory Usage

Memory-Efficient Processing

func (p *Plugin) processLargePDF(content []byte) error {
    // Process in chunks to manage memory
    if len(content) > MaxPDFSize {
        return errors.New("PDF too large")
    }
    
    // Use streaming for large files
    reader := bytes.NewReader(content)
    
    // Clean up explicitly
    defer func() {
        content = nil
        runtime.GC()
    }()
    
    return nil
}

Testing API

Test Helpers

LoadTestPDF

func LoadTestPDF(filename string) []byte

Description: Loads test PDF data for unit tests.

CreateMockPlugin

func CreateMockPlugin() *Plugin

Description: Creates a mock plugin instance for testing.

AssertTransactionInfo

func AssertTransactionInfo(t *testing.T, expected, actual *TransactionInfo)

Description: Asserts transaction info equality in tests.

Test Data

var TestPDFs = map[string]string{
    "isbank_sample":   "testdata/isbank_receipt.pdf",
    "garanti_sample":  "testdata/garanti_receipt.pdf", 
    "akbank_sample":   "testdata/akbank_receipt.pdf",
}

Integration Examples

Custom Field Extraction

// Add custom field extraction
func (p *Plugin) extractCustomField(text, pattern string) (string, error) {
    regex := regexp.MustCompile(pattern)
    matches := regex.FindStringSubmatch(text)
    if len(matches) < 2 {
        return "", errors.New("field not found")
    }
    return p.cleanText(matches[1]), nil
}

Webhook Integration

// Send extracted data to external webhook
func (p *Plugin) sendToWebhook(info *TransactionInfo) error {
    payload, _ := json.Marshal(info)
    
    resp, err := http.Post(webhookURL, "application/json", 
        bytes.NewBuffer(payload))
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    
    return nil
}

Support

For API-related questions: