Get key value store record
One script reply has been approved by the moderators Verified

This script returns a record from an Apify key-value store.

Created by jakub.drobnik222 88 days ago
Submitted by jakub.drobnik222 Bun
Verified 88 days ago
1
import { ApifyClient } from 'apify-client@^2.19.0';
2

3
type ApifyApiKey = {
4
  api_key: string;
5
};
6

7
type Apify = {
8
  token: string;
9
};
10

11
const createClient = (api_key?: ApifyApiKey, oauth_token?: Apify): ApifyClient => {
12
  const token = oauth_token?.token ?? api_key?.api_key;
13
  if (!token) {
14
    throw new Error('Missing Apify API key or OAuth token');
15
  }
16

17
  return new ApifyClient({
18
    token: token,
19
    requestInterceptors: [
20
      (request) => {
21
        if (!request.headers) {
22
          request.headers = {};
23
        }
24
        request.headers['x-apify-integration-platform'] = 'windmill';
25
        return request;
26
      },
27
    ],
28
  });
29
};
30

31
type DynSelect_store = string;
32
export async function store(api_key?: ApifyApiKey, oauth_token?: Apify) {
33
  if (!api_key?.api_key && !oauth_token?.token) {
34
    return [{ value: '', label: 'Missing Apify API key or OAuth token' }];
35
  }
36

37
  const apifyClient = createClient(api_key, oauth_token);
38

39
  try {
40
    const stores = await apifyClient.keyValueStores().list({
41
      desc: true,
42
    });
43

44
    return stores.items.map(item => ({
45
      value: item.id,
46
      label: item.title || item.name
47
    }));
48

49
  } catch (e: any) {
50
    return {
51
      error: `Failed to fetch Key-Value store list. Reason: ${e.message}`
52
    };
53
  }
54
}
55

56
type DynSelect_keys = string;
57
export async function keys(store: DynSelect_store, storeId: string, api_key?: ApifyApiKey, oauth_token?: Apify) {
58
  if (!api_key?.api_key && !oauth_token?.token) {
59
    return [{ value: '', label: 'Missing Apify API key or OAuth token' }];
60
  }
61

62
  const apifyClient = createClient(api_key, oauth_token);
63
  const id = storeId || store
64

65
  if (!id) {
66
    return {
67
      error: "Please select a store first to see its available keys."
68
    };
69
  }
70

71
  try {
72
    const keys = await apifyClient.keyValueStore(id).listKeys();
73

74
    return keys.items.map(item => ({
75
      value: item.key,
76
      label: item.key
77
    }));
78

79
  } catch (e: any) {
80
    return {
81
      error: `Failed to fetch keys for store "${id}". Reason: ${e.message}`
82
    };
83
  }
84
}
85

86
export async function main(
87
  key: DynSelect_keys,
88
  store?: DynSelect_store,
89
  storeId?: string,
90
  api_key?: ApifyApiKey,
91
  oauth_token?: Apify,
92
) {
93

94
  const id = storeId || store;
95

96
  if (!id) {
97
    return {
98
      error: "Store ID is required. Please select one from the list or provide it manually."
99
    };
100
  }
101

102
  if (!key) {
103
    return {
104
      error: "Please select a record key."
105
    };
106
  }
107

108
  const apifyClient = createClient(api_key, oauth_token);
109

110
  try {
111
    const record = await apifyClient.keyValueStore(id).getRecord(key);
112

113
    if (!record) {
114
      return { error: `Record with key "${key}" could not be found in store "${id}".` };
115
    }
116

117
    // Using Windmill's special return types for rich UI rendering
118
    switch (record.contentType) {
119
      case "image/png":
120
      case "image/jpeg":
121
        const imageType = record.contentType.split('/')[1];
122
        if (record.value instanceof Buffer) {
123
          return {
124
            [imageType]: {
125
              content: record.value.toString('base64'),
126
            },
127
          };
128
        } else if (typeof record.value === 'string') {
129
          return {
130
            [imageType]: record.value
131
          };
132
        }
133

134
        return { error: `Unsupported image type: ${typeof record.value}` };
135

136
      case "image/svg+xml":
137
        return {
138
          "svg": record.value,
139
        };
140

141
      case "text/html": {
142
        return {
143
          "html": record.value,
144
        };
145
      }
146

147
      case "text/plain":
148
        return record.value;
149

150
      default:
151
        if (record.value instanceof Buffer) {
152
          const base64string = (record.value as Buffer).toString('base64');
153
          return {
154
            "file": {
155
              content: base64string,
156
              filename: record.key || "download"
157
            },
158
          };
159
        }
160

161
        return record.value;
162
    }
163

164
  } catch (e: any) {
165
    return { error: `Failed to fetch record "${key}" from store "${id}". Reason: ${e.message}` };
166
  }
167
}