写了个自动加所有Amex offer到所有卡的script (仅供学习)

  1. 你的卡必须有那个offer才能加
  2. 登陆amex后,右键“inspect“, 点选console
  3. copy 以下script到console然后enter即可
  4. 更改concurrent的数字可以改单次request并发数量,怕死的改成1就好。
  5. 如果看到400或403 error,无视即可
  • 400: offer is not available for the card
  • 403: offer is already added to the card
var concurrent = 10; 

var API = {
    GET_ALL_ACCTS: 'https://apigw.americanexpress.com/servicing/v1/contact_management/chats/inquiry_results',
    GET_ALL_OFFERS: 'https://global.americanexpress.com/api/servicing/v1/offers?status=ELIGIBLE,ENROLLED',
    ADD_OFFER: 'https://global.americanexpress.com/api/servicing/v1/offers/'
};

var PAYLOAD = {
    getAllAccounts: {
        method: 'POST',
        credentials: 'include',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({
            'appVersion': '10.2.1',
            'authorizationType': 'USER_JWT',
            'browser': 'Chrome 116.0.0.0',
            'cacheStatus': true,
            'channel': 'web',
            'deviceOs': 'macOS 10.15.7',
            'deviceType': 'desktop',
            'environment': 'prod',
            'lob': 'MYCA',
            'locale': 'en-US',
            'pageUrl': 'https://global.americanexpress.com/dashboard',
            'targetingTopic': 'Navigation',
            'clientSourceId': ''
        })
    },
    getAllOffers: (account) => ({
        method: 'GET',
        headers: {
            'Account_token': account,
            'Timezone_offset': '-04:00',
            'Content-Type': 'application/json'
        }
    }),
    addOffers: (account) => ({
        method: 'PUT',
        headers: {
            'Timezone_offset': '-04:00',
            'Content-Type': 'application/json',
            'Account_token': account
        }
    })
};


var getAllOffers = async (accounts) => await Promise.all(
    accounts.map(account =>
        fetch(API.GET_ALL_OFFERS, PAYLOAD.getAllOffers(account))
            .then(response => response.json())
            .then(({offers}) => offers.filter(({ category, status }) => category !== 'DEFAULT' && status !== 'ENROLLED'))
            .catch(() => [])
            .then(offers => ({account, offers}))
    ));


var addOffersToCards = async (accountsAndOffers) => {
    try {
        for (let { account, offers } of accountsAndOffers) {
            for (let i = 0; i < offers.length; i += concurrent) {
                const offersBatch = offers.slice(i, i + concurrent);
                const fetchPromises = offersBatch.map(({ id }) =>
                    fetch(`${API.ADD_OFFER}${id}`, PAYLOAD.addOffers(account))
                );
                await Promise.all(fetchPromises);
            }
        }
        console.log('Complete');
    } catch (error) {
        console.error('Error adding offers to cards:', error);
    }
};

var getAllAccountRequest = fetch(API.GET_ALL_ACCTS, PAYLOAD.getAllAccounts)
    .then(response => response.json())
    .then(result => Object.keys(result.data.creditStatusInfo.creditStatusKeys));

console.log('Start to adding all offers, please wait...');
await getAllAccountRequest
    .then(getAllOffers)
    .then(addOffersToCards)

3 个赞

早晚搞坏

辛苦了,赞

1 个赞

做得好,但是论坛里已经有更好的了 :yaoming:

呵呵, 所以我把标题设为“仅供学习”
而且这个不需要下载任何东西,直接浏览器就搞定

1 个赞

这是什么神仙编程语言……?

大佬 同时发这么多请求会被当成bot的

能在浏览器console里跑的还能是啥?
当然是WebAssmbly

厉害了:+1: 学习学习

把里面的concurrent数字10 改成自己喜欢的数字就好

我还真去看了一下咋写的 web assembly,不就是 native js 吗

就是javascript。。。

不一定啊,只要浏览器愿意,想host啥语言都可以啊。是我想象力过于丰富了 :yaoming:

不是,主要还是,我拒绝相信JS这种语言能活到现在啊……

最后一句是搞笑用的

js 是个筐,什么都能往里装,你别写 native js 就好了

  • pure functional js
  • typescript
  • reactive js

不过现在也可以把什么东西都往 web assembly 编译了,希望以后的逆向不会变太难

可用 不过还是一个offer只能加到一张卡上

自从18年amex就在修concurrency的问题了,估计是终于修好了:多页面/账户添加 Amex Offers 已死 - 美国信用卡指南